decltype作为类成员函数中的返回类型

时间:2013-05-21 09:16:38

标签: c++ c++11 decltype

我在代码下面编译错误。

struct B{
    double operator()(){
        return 1.0;
    }
};

struct A {
    auto func() -> decltype(b())
    {
        return b();
    }

    B b;
};

但是,如果我重组A,它会编译。

gcc 4.8说'b'未在此范围内声明。

struct A {
    B b;
    auto func() -> decltype(b())
    {
        return b();
    }
};

那么,第一个是什么问题?

3 个答案:

答案 0 :(得分:11)

  

有效吗?

你的最后一个例子是格式良好的,而第一个例子不是(所以GCC是正确的)。

关于非限定名称查找的第3.4.1 / 7段规定:

  

在成员函数体之外的类X 的定义中使用的名称,默认参数,大括号 - 或 -   非静态数据成员的等于初始化程序,或嵌套类定义应在其中一个中声明   以下方式

     

- 在用于课程X 之前,或者是X(10.2)基类的成员,或

     

- [...]

以下是其他不适用于您的情况。

答案 1 :(得分:9)

class的定义经过两次处理:首先收集成员声明,​​包括函数签名,然后解析定义的主体。

因此,函数体可以访问所有成员声明,​​包括后续声明,但函数原型只能看到前面的声明。

答案 2 :(得分:1)

你也可以这样工作:

struct B
{
    double operator()()
    {
        return 1.0;
    }
};

// my implementation does not have std::declval
template < typename T > T&& declval();

struct A
{
    B b;
    auto func() -> decltype(declval<B>().operator()())
    {
        return b();
    }
};

编辑: 或者因为B已经在范围内,无论如何不需要自动, - &gt; decltype和declval

struct A
{
    B b;
    decltype(Q()()) func()
    {
        return b();
    }
};