【问题标题】:Using the this pointer inside decltype在 decltype 中使用 this 指针
【发布时间】:2012-06-18 23:42:28
【问题描述】:

示例(编译良好)

struct A
{
    void f() {};
    auto g() -> decltype(f())
    {}

};

问题

如果我在 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 吗?有人可以帮助我了解问题所在吗?

编辑

This has been filed as a bug.

【问题讨论】:

    标签: c++ gcc c++11 decltype


    【解决方案1】:

    看来问题不在于this 出现在decltype 内,而在于它出现在函数体之外。

    对于示例,以下代码在 GCC 4.7 下编译:

    struct A
    {
      int f() { return 0; }
      auto g() -> decltype(f()) {
        decltype(this->f()) var = this->f();
        return var;
      }
    };
    

    这里使用decltype(this->f())insideg的主体,但是在auto .... -> ....形式中指定函数的返回类型,即所谓的尾随返回type 规范,不是函数体的一部分,GCC 不允许它存在。

    然而,看起来(见 cmets 中的讨论)C++ 标准实际上并不要求在函数体中使用 this:标准的第 5.1.1 节规定 @ 987654328@ 可以在可选的 const/volatile 限定符和函数体结尾之间的任何地方使用,请参见下面的第 3 节。 (为了完整起见,我也添加了第 4 条,它讨论了数据成员,与问题没有直接关系)。

    (第 3 条)如果声明声明了类 X 的成员函数或成员函数模板,则表达式 this 是可选的 cv-qualifer-seq 和 函数定义、成员声明符或声明符。 它不应出现在可选的 cv-qualifier-seq 之前 并且它不应出现在静态成员函数的声明中(尽管它的类型和值 类别在静态成员函数中定义,就像它们在非静态成员函数中一样)。 [...]

    (第 4 条)否则,如果成员声明符声明类 X 的非静态 数据成员 (9.2),则表达式 this 是“指向 X 的指针”类型的纯右值在可选的大括号或等式初始化器中。它不应出现在其他地方 在成员声明器中。

    (第 5 条)表达式 this 不得出现在任何其他上下文中。 [...]

    注意:正如 Jesse 在评论中指出的那样,可选的 cv-qualifier-seq,即函数的 constvolatile 限定符必须出现 尾随返回类型声明之前。因此以问题中描述的方式使用this应该是正确的,而GCC似乎是错误的。

    【讨论】:

    • 发布实际的 §5.1.1 引文将使此答案完整。
    • @ildjarn 如果你坚持...给你。
    • 如果你真的想显式,你也可以使用std::declval<A>().foo(),因为它的参数可能是不完整的类型。
    • 谢谢,这很有帮助。但是,除非我的解释是错误的,否则尾随返回类型不会出现在 cv-qualifier-seq?? 之后
    • @Jesse Good 你是对的。我没想到。毕竟 GCC 可能是错的。
    【解决方案2】:

    错误消息似乎很清楚:“this”是“struct A”的一个实例,它是一个不完整的类型(即编译器在当前传递期间尚未完成对结构的解析)。

    【讨论】:

    • decltype 应该在某种程度上允许完整的类型(参见N2343N3276)。您是在解释编译器错误,但并未断言编译器是正确还是不正确以首先给出该错误。
    • 如果是这种情况,我认为使用decltype(f()) 访问类的成员函数也会导致编译器错误。
    • @ildjarn 很公平 - 我相信编译器给出这个错误是正确的。
    • 从同一类的另一个方法中调用一个方法对我来说一直意味着隐含的this 被取消引用。我认为gcc 必须添加一些特殊情况代码以在declspec 中以不同方式处理调用。
    • 这已被认定为 gcc 中的一个错误。
    猜你喜欢
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-31
    • 2021-12-25
    • 1970-01-01
    相关资源
    最近更新 更多