Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么声明顺序对于作为模板参数传递成员函数指针很重要?_C++_Templates_Member Pointers - Fatal编程技术网

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() {}
};