使用decltype作为构造函数参数



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

class A
{
public:
    A(decltype(b_) b)
        : b_{b}
    {}
private:
    std::function<void(int, std::string, float)> b_;
};
// error: ‘b_’ was not declared in this scope

而只需更改申报顺序即可:

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

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

这与已完成的类上下文有关。一个类被视为已完成,仅在:中

  • 函数体([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_;
};

b_还没有被看到,所以您得到了一个编译器错误。带

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

已经看到了b_,所以以后在类中使用它不会出错。

最新更新