使用 decltype 作为构造函数参数

Dom*_*kar 1 c++ c++17

我很好奇为什么在这种情况下成员声明的顺序是一个问题:

\n\n
class A\n{\npublic:\n    A(decltype(b_) b)\n        : b_{b}\n    {}\n\nprivate:\n    std::function<void(int, std::string, float)> b_;\n};\n\n// error: \xe2\x80\x98b_\xe2\x80\x99 was not declared in this scope\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

而仅更改声明顺序即可:

\n\n
class A\n{\n    std::function<void(int, std::string, float)> b_;\n\npublic:\n    A(decltype(b_) b)\n        : b_{b}\n    {}\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

由于 gcc 和 Clang 都以相同的方式处理它,我会说这不是一个错误,但我仍然觉得它令人困惑。

\n

Nat*_*ica 5

这与完成的课程背景有关。只有在以下情况下,课程才被视为已完成:

  • 函数体([dcl.fct.def.general]),

  • 默认参数,

  • noexcept 说明符,或

  • 默认成员初始值设定项

并且成员函数的参数列表不是其中的一部分。这意味着您使用的任何类型都需要被编译器知道(看到)。在

class A
{
public:
    A(decltype(b_) b) <- class not complete here
        : b_{b}       <- class is complete here since the mem-initializer list is part of [dcl.fct.def.general]
    {}                <-/

private:
    std::function<void(int, std::string, float)> b_;
};
Run Code Online (Sandbox Code Playgroud)

b_还没有见过,所以你会得到一个编译器错误。和

class A
{
    std::function<void(int, std::string, float)> b_;

public:
    A(decltype(b_) b)
        : b_{b}
    {}
};
Run Code Online (Sandbox Code Playgroud)

b_已经看到了,所以稍后在课堂上使用它不会出现错误。