1

I just encountered a problem with the CRTP, where I can't have the same method name (with a different signature) in both the base and derived class. The example to reproduce this issue is the following :

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
}

I tried this under various versions of GCC, clang and even ICC using godbolt

Anybody could explain what is at work here ?

GCC output:

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;}
Lectem
  • 503
  • 6
  • 19

1 Answers1

2

It has nothing to do with CRTP, just that the Derived::foo shadows Base::foo, just as if you had declared a foo in an inner scope.

One way to un-shadow the Base version, is to [1]place a

using Base<Derived>::foo;

in Derived.


[1] Full example at (http://coliru.stacked-crooked.com/a/5dc7558e12babbe5).

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • I just saw that the CRTP indeed had nothing to play here, I didn't know that such shadowing did exist, thanks ! For reference see http://stackoverflow.com/a/411116/3781105 – Lectem Feb 03 '16 at 04:28
  • @Lectem: Johannes' answer there is good, but the selected-as-solution answer is not. – Cheers and hth. - Alf Feb 03 '16 at 04:49
  • yeah I took the wrong link, but couldn't edit my comment anymore. If anybody needs to see what the standard says, here is Johannes' answer: http://stackoverflow.com/a/411112/3781105 – Lectem Feb 03 '16 at 04:52