ikh*_*ikh 23 c++ templates member-pointers
看看这段代码:
template <typename T, void (T::*pfn)()> struct Testee {};
class Tester
{
private:
void foo() {}
public:
using type_t = Testee<Tester, &Tester::foo>;
};
Run Code Online (Sandbox Code Playgroud)
它成功编译g++ -std=c++14 -Wall -Wextra.
但是,当我改变的顺序foo和type_t,发生错误:
$ 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>;
^
Run Code Online (Sandbox Code Playgroud)
通常,类定义中的声明顺序对名称解析没有影响.例如:
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) { }
};
Run Code Online (Sandbox Code Playgroud)
但是,它在这种情况下有效.为什么?
asc*_*ler 33
这与模板无关.你得到一个类似的错误:
class Tester
{
public:
using type_t = decltype(&Tester::foo);
private:
void foo() {}
};
Run Code Online (Sandbox Code Playgroud)
一个类确实是(标准9.2/2):
视为功能体,默认参数内完成,使用-声明引入继承构造(12.9),例外的规范,和 支架-或等于-初始化用于非静态数据成员(包括嵌套类这样的事情).
但是,成员类型的定义不在该列表中,因此它只能使用在该点之前声明的名称.