这是一个语言律师问题。 C ++ 11中的第5p5条规定:
如果表达式最初具有“对T的引用”类型(8.3.2,8.5.3),则类型在之前调整为T 进一步的分析。表达式指定由引用表示的对象或函数,以及 表达式是左值或左值,具体取决于表达式。
另一方面,§5.2.2p3声明:
如果postfix-expression指定析构函数(12.4),则函数调用表达式的类型为void; 否则,函数调用表达式的类型是静态选择函数的返回类型(即, 忽略虚拟关键字),即使实际调用的函数类型不同。这种类型 是对象类型,引用类型或类型void。
考虑这段代码:
int& f();
f(); // What is the type of this expression?
答案 0 :(得分:2)
在DR 1261的标准发布后,这已得到纠正。草案n3485内容如下:
[...]否则,函数调用表达式的类型是静态选择函数的返回类型(即, 忽略
virtual
关键字),即使实际调用的函数类型不同。此返回类型 应为对象类型,引用类型或cv
void
。
(我的重点;不在你的引言中)。
这两段现在兼容;函数调用表达式的(初始)类型现在是int &
,它会立即调整为int
和值 - 类别左值。返回限定类型的函数会发生类似的过程,这样做的好处是我们不需要担心左值到参考的转换:
const int g();
static_assert(std::is_same<decltype(g()), int>::value, "!!!");
答案 1 :(得分:0)
f()
的类型为int
;它的价值类别是左值。你可以证明这一事实:
int& f();
static_assert(std::is_same<int&,decltype((f()))>::value,"EXPLODE");
根据C ++11§7.1.6.2[dcl.type.simple] / 4“......如果e
是左值,decltype(e)
是T&
,其中T
1}}是e
“的类型。
答案 2 :(得分:0)
示例代码:
int& foo() { static int x; return x; }
int bar() { return 0; }
template< class Type >
struct Is_ref_ { static const bool yes = false; };
template< class Type >
struct Is_ref_<Type&> { static const bool yes = true; };
#include <iostream>
using namespace std;
auto main() -> int
{
cout << boolalpha;
cout << "Function calls foo versus bar:" << endl;
cout << Is_ref_<decltype(foo())>::yes << endl;
cout << Is_ref_<decltype(bar())>::yes << endl;
int a;
int& b = a;
cout << endl;
cout << "lvalue versus ref:" << endl;
cout << Is_ref_<decltype(a)>::yes << endl;
cout << Is_ref_<decltype(b)>::yes << endl;
}
使用Visual C ++ 12.0和MinGW g ++ 4.7.2输出:
函数调用foo与bar:
真正
假的左值与参考:
假
真的