C++ 在decltype中使用this指针

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

示例(编译精细)

问题

如果我在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 '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;
  }
};