I just noticed this behavior in own code, so here is the naive question:
This:
struct A
{
int get()
{
return a;
}
int a=1;
};
int main() {}
Compiles of course fine, although when the declaration of member data lies after the function definition.
But then I don't understand why this:
struct A
{
auto get() -> decltype(a)
{
return a;
}
int a=1;
};
does not compile(*). I have to write this:
struct A
{
int a=1;
auto get() -> decltype(a)
{
return a;
}
};
Is there any language-related reasons why it's not ok, or is it just that the compilers have not implemented that ? I would expect to have the same behavior regardless of the order of the class members.
(*) tested with gcc 6.3 through Ideone.com
In your first example, A::get
is declared, then A::a
is declared, and only then (because A
is fully declared), A::get
is defined. At this point, in A::get
, the compiler knows about A::a
.
Consider this equivalent form:
struct A
{
int get();
int a=1;
};
inline int A::get()
{
return a;
}
This would not be compilable for you second example:
struct A
{
auto get() -> decltype(a); // What is "a"?
int a=1;
};
inline auto A::get() -> decltype(A::a)
{
return a;
}
The same "order of declaration" has to be respected when you declare types, for example:
struct A
{
using IntType = int;
auto get() -> IntType;
int a=1;
};
You couldn't write like so:
struct A
{
using IntType = decltype(a);
auto get() -> IntType;
int a=1;
};
Also note that this is not limited to return types: parameter types are also part of a function declaration. So this doesn't compile either:
struct A
{
void f(decltype(a));
int a=1;
};
An informal answer if I may: decltype
is a red herring.
All parts of a return
type need to have already been seen by the compiler on the first pass.
For example,
template <size_t N> struct T{};
struct A
{
T<sizeof(a)> get()
{
return T<sizeof(a)>();
}
int a;
};
will also fail, for the same reason: compilation passes if int a;
is seen before get()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With