为什么decltype没有看到成员声明?

Bul*_*net 27 c++ c++11

试图编译这个简单的类:

#include <vector>
struct M
{
// interface
    auto begin() -> decltype(identities.begin())
    {
        return identities.begin();
    }
// implementation
private:
    std::vector<int> identities;
};
Run Code Online (Sandbox Code Playgroud)

导致错误:

$ g++-510 where.cpp -std=c++11
where.cpp:57:35: error: ‘struct M’ has no member named ‘identities’
     auto begin() ->decltype(this->identities.begin())
                                   ^
where.cpp:57:35: error: ‘struct M’ has no member named ‘identities’

$ clang++ where.cpp -std=c++11 -Wall -pedantic -Wextra
where.cpp:57:35: error: no member named 'identities' in 'M'
    auto begin() ->decltype(this->identities.begin())
                            ~~~~  ^
Run Code Online (Sandbox Code Playgroud)

为什么decltype看不到班级成员?

Tar*_*ama 23

来自N3337 [basic.lookup.unqual]/7:

在成员函数体或嵌套类定义之外的类X的定义中使用的名称应以下列方式之一声明:

  • 在X类中使用之前或者是X的基类的成员,或者......

因为尾部返回类型是函数声明的一部分而不是定义,所以它无法向前看以查看类中声明的其他内容,因此您需要在函数声明之上声明该成员.


Ant*_*vin 16

如果C++ 14可用,则可以省略尾随返回类型,从而避免引用函数体外的成员并使代码更紧凑:

auto begin() {
    return identities.begin();
}
Run Code Online (Sandbox Code Playgroud)

一般来说,使用decltype(auto)这种转发方法更为正确,因此返回类型可以作为参考,但在这种特殊情况下它是相同的(感谢@Nawaz):

decltype(auto) begin() {
    return identities.begin();
}
Run Code Online (Sandbox Code Playgroud)