函数调用表达式的类型是什么?

时间:2013-12-20 15:58:24

标签: c++ c++11 types reference expression

这是一个语言律师问题。 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?

3 个答案:

答案 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:
  真正
  假的

     

左值与参考:
  假
  真的