C++ 为什么声明顺序对于作为模板参数传递成员函数指针很重要?
请看以下代码:C++ 为什么声明顺序对于作为模板参数传递成员函数指针很重要?,c++,templates,member-pointers,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>; }; 通常,类定义中声明的顺序对名称解析没有影响。例如: struct A // OK { void foo(int
template <typename T, void (T::*pfn)()> struct Testee {};
class Tester
{
private:
void foo() {}
public:
using type_t = Testee<Tester, &Tester::foo>;
};
通常,类定义中声明的顺序对名称解析没有影响。例如:
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) { }
};
然而,在这种情况下,它会产生影响。为什么?这实际上与模板无关。你会在以下方面得到类似的结果: 的确,类是(标准9.2/2): 在功能体中被认为是完整的, 默认参数,使用引入继承构造函数(12.9)、异常规范和 非静态数据成员(包括嵌套类中的此类对象)的大括号或相等初始值设定项 但是,成员类型的定义不在该列表中,因此它只能使用在该点之前声明的名称
通常,类定义中声明的顺序没有影响 那太夸张了。据我所知,允许对类定义后面出现的声明进行一些使用:
- 默认参数(如您所述;但不是默认模板参数)
- 在函数体、函数try块或成员初始值设定项中使用
- 类内初始值设定项(C++11或更高版本)
此外,如前所述,数据成员的顺序会影响构造和销毁顺序。此外,在翻译单元之间重新排序可能会令人惊讶地导致ODR冲突。您尝试过其他编译器吗?“类定义中的声明顺序没有影响”好吧,通常情况下这并不完全正确,例如,成员是按照它们的顺序构造的declared@tobi303在这种情况下,没有构造(即根本没有召集选举主任)@卢卡卡帕我知道,我只是说,总的来说,这项声明并不正确true@max嗯,我试过clang++,效果也一样。我喜欢这个答案是因为另一个例子和标准引用。如果你速度快,我会选择this@ikh你可以随时改变你的选择,但这说明了为什么在接受a之前等待一段时间是个好主意如果有更好的答案出现,请回答。这是正确的答案。速度和正确性并不总是相关的。接受错误的答案会给以后阅读本页的人带来困惑。
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) { }
};
class Tester
{
public:
using type_t = decltype(&Tester::foo);
private:
void foo() {}
};