CRTP with derived class 重载方法

CRTP with derived class overloading the method

我刚刚遇到 CRTP 的问题,我不能在基础和派生 class 中使用相同的方法名称(具有不同的签名)。重现此问题的示例如下:

template <class T>
struct Base
{
    void foo(){}
    void bar(){
        static_cast<T*>(this)->foo(1,1);
    }
};

struct Derived : public Base<Derived>
{
    int foo(int a,int b){ return a+b;}
};

int test()
{
  Derived d;
  d.bar(); // works
  d.foo(1,1); // obviously works
  d.foo(); // compilation error
}

我在各种版本的 GCC、clang 甚至 ICC 下使用 godbolt

进行了尝试

有人可以解释这里的工作原理吗?

GCC 输出:

In function 'int test()':
22 : error: no matching function for call to 'Derived::foo()'
d.foo(); // doesn't work
^
13 : note: candidate: int Derived::foo(int, int)
int foo(int a,int b){ return a+b;}

它与CRTP无关,只是Derived::foo shadows Base::foo,就像你声明了一个foo在内部范围内。

取消隐藏 Base 版本的一种方法是 [1]放置一个

using Base<Derived>::foo;

Derived.


[1] 完整示例位于 (http://coliru.stacked-crooked.com/a/5dc7558e12babbe5)。