keb*_*ebs 12 c++ decltype language-lawyer c++11
我只是在自己的代码中注意到了这种行为,所以这是一个天真的问题:
这个:
struct A
{
int get()
{
return a;
}
int a=1;
};
int main() {}
Run Code Online (Sandbox Code Playgroud)
编译当然很好,虽然当成员数据的声明谎言之后的函数定义.
但后来我不明白为什么这样:
struct A
{
auto get() -> decltype(a)
{
return a;
}
int a=1;
};
Run Code Online (Sandbox Code Playgroud)
不编译(*).我要写这个:
struct A
{
int a=1;
auto get() -> decltype(a)
{
return a;
}
};
Run Code Online (Sandbox Code Playgroud)
有什么语言相关的原因,为什么它不好,或者只是编译器没有实现它?无论类成员的顺序如何,我都希望有相同的行为.
(*)通过Ideone.com使用gcc 6.3进行测试
在你的第一个例子中,A::get声明,然后A::a声明,然后才定义(因为A完全声明)A::get.此时A::get,编译器知道A::a.
考虑这种等效形式:
struct A
{
int get();
int a=1;
};
inline int A::get()
{
return a;
}
Run Code Online (Sandbox Code Playgroud)
对于第二个例子,这不可编译:
struct A
{
auto get() -> decltype(a); // What is "a"?
int a=1;
};
inline auto A::get() -> decltype(A::a)
{
return a;
}
Run Code Online (Sandbox Code Playgroud)
声明类型时必须遵守相同的"声明顺序",例如:
struct A
{
using IntType = int;
auto get() -> IntType;
int a=1;
};
Run Code Online (Sandbox Code Playgroud)
你不能这样写:
struct A
{
using IntType = decltype(a);
auto get() -> IntType;
int a=1;
};
Run Code Online (Sandbox Code Playgroud)
另请注意,这不仅限于返回类型:参数类型也是函数声明的一部分.所以这也不编译:
struct A
{
void f(decltype(a));
int a=1;
};
Run Code Online (Sandbox Code Playgroud)
如果可能的话,一个非正式的回答:decltype是一个红鲱鱼.
return编译器在第一次传递时需要看到类型的所有部分.
例如,
template <size_t N> struct T{};
struct A
{
T<sizeof(a)> get()
{
return T<sizeof(a)>();
}
int a;
};
Run Code Online (Sandbox Code Playgroud)
也会因为同样的原因而失败:如果int a;以前见过编译通过get().
| 归档时间: |
|
| 查看次数: |
299 次 |
| 最近记录: |