Reputation: 1743
I'm curious as to why the order of member declaration in this case is an issue:
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
while just changing the declaration order works:
class A
{
std::function<void(int, std::string, float)> b_;
public:
A(decltype(b_) b)
: b_{b}
{}
};
Since both gcc and Clang handle it in the same manner I'd say that it's not a bug but I still find it confusing.
Upvotes: 2
Views: 683
Reputation: 180965
This has to do with the completed-class context. A class is considered completed, only in:
function body ([dcl.fct.def.general]),
default argument,
noexcept-specifier, or
default member initializer
and the parmeter list of a member function is not a part of that. That means that any type you use needs to already be known (seen) by the compiler. In
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_
has not been seen yet, so you get a compiler error. With
class A
{
std::function<void(int, std::string, float)> b_;
public:
A(decltype(b_) b)
: b_{b}
{}
};
b_
has been seen, so there is no error using it later on in the class.
Upvotes: 7