我在代码下面编译错误。
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();
}
};
那么,第一个是什么问题?
答案 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();
}
};