[英]Why is declaration order important for passing a member function pointer as a template argument?
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
. 它成功地用
g++ -std=c++14 -Wall -Wextra
。
However, when I change the order of foo
and type_t
, an error occurs: 但是,当我更改
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>;
^
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?
为什么?
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): 一个类确实是(标准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).
在函数体,默认参数,引用继承构造函数(12.9)的使用声明 , 异常规范和非静态数据成员的括号或等于初始化器 (包括嵌套类中的这类事物)中被认为是完整的。
However, the definition of a member type is not in that list, so it can only use names declared before that point. 但是,成员类型的定义不在该列表中,因此它只能使用在该点之前声明的名称。
Usually, the order of declaration in class definition have no effects.
通常,类定义中的声明顺序没有效果。
That's quite an overstatement. 这是夸大其词。 A few uses of declarations that appear later in the class definition are allowed, to the best of my knowledge:
根据我的知识,允许在类定义中稍后出现的一些声明用法:
Also, as has been mentioned, the order of data members affects construction and destruction order. 而且,如上所述,数据成员的顺序影响构造和销毁顺序。 Also, reordering stuff between translation units may surprisingly cause an ODR violation.
此外,翻译单元之间的重新排序可能会令人惊讶地导致ODR违规。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.