Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is declaration order important for passing a member function pointer as a template argument?

Tags:

Look at this code:

template <typename T, void (T::*pfn)()> struct Testee {};  class Tester { private:     void foo() {} public:     using type_t = Testee<Tester, &Tester::foo>;     }; 

It successfully compiles with g++ -std=c++14 -Wall -Wextra.

However, when I change the order of foo and type_t, an error occurs:

$ cat test.cpp template <typename T, void (T::*pfn)()> struct Testee {};  class Tester { public:     using type_t = Testee<Tester, &Tester::foo>; private:     void foo() {} };  int main() { }  $ g++ -std=c++14 -Wall -Wextra -pedantic test.cpp test.cpp:6:36: error: incomplete type ‘Tester’ used in nested name specifier      using type_t = Testee<Tester, &Tester::foo>;                                     ^ test.cpp:6:47: error: template argument 2 is invalid      using type_t = Testee<Tester, &Tester::foo>;                                                ^ 

Usually, the order of declarations in class definitions has no effect on name resolving. For example:

struct A // OK {     void foo(int a = val) { }     static constexpr const int val = 42; };  struct B // OK {     static constexpr const int val = 42;     void foo(int a = val) { } }; 

However, it has an effect in this case. Why?

like image 633
ikh Avatar asked Jun 09 '17 11:06

ikh


1 Answers

This is not really related to templates. You get a similar error on:

class Tester { public:     using type_t = decltype(&Tester::foo); private:     void foo() {} }; 

It's true that a class is (Standard 9.2/2):

regarded as complete within function bodies, default arguments, using-declarations introducing inheriting constructors (12.9), exception-specifications, and brace-or-equal-initializers for non-static data members (including such things in nested classes).

However, the definition of a member type is not in that list, so it can only use names declared before that point.

like image 158
aschepler Avatar answered Oct 02 '22 21:10

aschepler