通过推导出此引用来解决调用大多数派生方法时的编译错误

问题描述 投票:0回答:1

我有以下使用推导此模式的代码:

#include <print>

struct base
{
   template <typename Self>
   void invoke(this Self& self)
   {
      self.foo();
   }
};

struct derived : base
{
   void foo() { std::println("derived::foo()"); }
};

int main()
{
   derived d;
   d.invoke(); // ok

   base& bref = d;
   bref.invoke(); // error

   base* bptr = &d;
   bptr->invoke(); // error

   return 0;
}



编译器生成以下错误:

<source>:8:12: error: no member named 'foo' in 'base'
    8 |       self.foo();
      |       ~~~~ ^
<source>:23:6: note: in instantiation of function template specialization 'base::invoke<base>' requested here
   23 |    bref.invoke(); // error
      |      ^

考虑到编译器生成的错误,用于推论的基类型是否与使用正常运行时多态性时期望的类型不同?

c++ this
1个回答
0
投票

考虑到编译器生成的错误,用于推论的基类型是否与使用正常运行时多态性时期望的类型不同?

推导出

this
编译时多态性,就像一般的模板一样。

对于程序中

invoke
的任何给定使用,将推导
Self
的类型,并在该类型中查找函数
foo
,并且只能调用该函数。不涉及运行时多态性。对于运行时多态性,您需要
virtual
函数。

当您在类型为

invoke
而不是
base
的表达式上调用
derived
时,则
Self
以及
self
invoke
的类型也将是
base
。在其中的
foo
foo` 函数中查找
base´ will not find anything, because you never declared a 

对于运行时多态性,您需要在

foo
中将
virtual
声明为
base
,然后无论
invoke
是在基类还是派生类型上调用,它都会按照您的预期工作。但是,在这种情况下,该函数根本不需要使用 deduced-
this
。普通的非静态成员函数就可以了,就像直接调用
foo
一样,而不是通过
invoke

© www.soinside.com 2019 - 2024. All rights reserved.