C++ 在decltype中使用this指针
示例(编译精细) 问题 如果我在decltype中添加C++ 在decltype中使用this指针,c++,gcc,c++11,decltype,C++,Gcc,C++11,Decltype,示例(编译精细) 问题 如果我在decltype中添加this指针(即decltype(this->f())),我会在gcc 4.7.0中遇到以下编译错误: error: invalid use of incomplete type 'struct A' error: forward declaration of 'struct A' error: invalid use of incomplete type 'struct A' error: forward declaration of 's
this
指针(即decltype(this->f())
),我会在gcc 4.7.0中遇到以下编译错误:
error: invalid use of incomplete type 'struct A'
error: forward declaration of 'struct A'
error: invalid use of incomplete type 'struct A'
error: forward declaration of 'struct A'
是否不允许在decltype中使用此
?有人能帮我理解问题出在哪里吗
编辑
.错误消息似乎非常清楚:“this”是一个不完整类型的“struct A”实例(即编译器在当前过程中尚未完成对结构的解析) 问题似乎不是
此
出现在decltype
内部,而是它出现在函数体外部。
对于示例,以下代码在GCC 4.7下编译:
struct A
{
int f() { return 0; }
auto g() -> decltype(f()) {
decltype(this->f()) var = this->f();
return var;
}
};
这在g
的主体中使用decltype(This->f())
,但在auto…->中指定函数的返回类型代码>形式,即所谓的尾随返回类型规范,不是函数体的一部分,GCC不允许它存在
<强> > <强>,将出现(参见评论中的讨论),C++标准实际上不要求<代码>此< /代码>用于函数体:标准代码的“5.1.1”,“<代码>此< /代码>可以在可选const /易失性限定符和函数体的末尾之间使用任何地方,参见下面的第3条。(为了完整起见,我还增加了第4条,该条涉及数据成员,与问题没有直接关系)
(第3条)如果声明声明类X的成员函数或成员函数模板,则表达式this
是可选cv限定符序列和序列末尾之间的“指向cv限定符序列X的指针”类型的PR值
功能定义、成员声明符或声明符它不应出现在可选cv限定符序列之前
并且它不应出现在静态成员函数的声明中(尽管其类型和值
类别在静态成员函数中定义,正如它们在非静态成员函数中定义一样)。[……]
(第4条)否则,如果成员声明符声明类X的非静态数据成员(9.2),则表达式
是可选大括号或等效初始值设定项中“指向X的指针”类型的prvalue。它不应出现在其他地方
在成员声明器中
(第5条)本一词不得出现在任何其他上下文中。[……]
注意:可选cv限定符seq,即函数的const
或volatile
限定符,正如Jesse在注释中指出的那样,必须出现在尾部返回类型声明之前。因此以问题中描述的方式使用此
应该是正确的,GCC似乎是错误的。decltype
应该在某种程度上允许完整的类型(参见vs.)。您解释的是编译器错误,但并不是断言编译器一开始就给出该错误是正确的或不正确的。如果是这种情况,请使用decltype(f())
访问该类的成员函数也会导致编译器错误。@ildjarn Fair-我相信编译器给出此错误是正确的。在我看来,从同一类的另一个方法中调用某个方法始终意味着此
被取消引用。我认为gcc
必须添加一些特殊案例代码,以便在declspec
中对呼叫进行不同的处理。这被认为是gcc中的一个错误。发布实际的§5.1.1引用将使此答案完整。@ildjarn如果您坚持。。。给你。如果你真的想显式,你也可以使用std::declval().foo()
,因为它的参数可能是一个不完整的类型。谢谢,这很有帮助。然而,除非我的解释是错误的,否则后面的返回类型不是在cv限定符seq之后吗?
?@Jesse Good你是对的。我没想到。毕竟,GCC可能是错误的。
struct A
{
int f() { return 0; }
auto g() -> decltype(f()) {
decltype(this->f()) var = this->f();
return var;
}
};