You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用推导this调用最派生方法时的编译错误及疑问

关于C++“推导this”模式与运行时多态类型不一致的疑问

示例代码

#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
      |      ^

疑问

使用“推导this”时所用的基类类型,为何与常规运行时多态中的预期类型不一致?

解析

这是因为推导this本质是编译期的模板参数推导,和运行时多态的动态绑定完全是两套机制:

  • 当通过derived对象调用invoke时,模板参数Self被推导为derived,self.foo()直接调用derived::foo(),因此正常运行。
  • 当通过base&或base*调用invoke时,模板推导只会看调用点的静态类型(也就是base),所以Self被推导为base。而base类中并没有定义foo方法,自然会触发编译错误——这个过程完全和运行时实际指向的derived对象无关。
  • 常规运行时多态依赖虚函数机制,是运行时行为:它会根据对象的实际类型(而非静态类型),通过虚函数表找到对应的函数调用。你的代码里foo不是虚函数,即便用推导this也无法实现这种动态匹配。

如果要在推导this模式下实现类似多态的效果,可以给基类添加虚函数:

struct base
{
   virtual void foo() = 0; // 纯虚函数,强制派生类实现
   template <typename Self>
   void invoke(this Self& self)
   {
      self.foo(); // 此时会触发动态绑定,调用实际类型的foo
   }
};

内容的提问来源于stack exchange,提问作者Penny Dreudter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 17:43:15