简体   繁体   English

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

[英]What's the type of the function call expression?

This is a language lawyer question. 这是一个语言律师问题。 Clause 5p5 in C++11 reads: C ++ 11中的第5p5条规定:

If an expression initially has the type “reference to T” (8.3.2, 8.5.3), the type is adjusted to T prior to any further analysis. 如果表达式最初具有“对T的引用”类型(8.3.2,8.5.3),则在进行任何进一步分析之前将类型调整为T. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression. 表达式指定由引用表示的对象或函数,表达式是左值或x值,具体取决于表达式。

On the other hand, §5.2.2p3 states: 另一方面,§5.2.2p3规定:

If the postfix-expression designates a destructor (12.4), the type of the function call expression is void; 如果postfix-expression指定析构函数(12.4),则函数调用表达式的类型为void; otherwise, the type of the function call expression is the return type of the statically chosen function (ie, ignoring the virtual keyword), even if the type of the function actually called is different. 否则,函数调用表达式的类型是静态选择函数的返回类型(即,忽略虚拟关键字),即使实际调用的函数的类型不同。 This type shall be an object type, a reference type or the type void. 此类型应为对象类型,引用类型或类型void。

Consider this piece of code: 考虑一下这段代码:

int& f();
f();  // What is the type of this expression?

This was corrected post publication of the standard, in DR 1261 . DR 1261中标准发布后,这已得到纠正。 Draft n3485 reads: 草案n3485内容如下:

[...] otherwise, the type of the function call expression is the return type of the statically chosen function (ie, ignoring the virtual keyword), even if the type of the function actually called is different. [...]否则,函数调用表达式的类型是静态选择函数的返回类型(即,忽略virtual关键字),即使实际调用的函数的类型不同。 This return type shall be an object type, a reference type or cv void . 返回类型应为对象类型,引用类型或cv void

(my emphasis; not in your quote). (我的重点;不在你的引言中)。

The two paragraphs are now compatible; 这两段现在兼容; the (initial) type of the function call expression is now int & , which gets adjusted to int and value-category lvalue immediately. 函数调用表达式的(初始)类型现在是int & ,它立即调整为int和value-category lvalue。 A similar process occurs with a function returning a qualified type, which has the advantage that we don't need to worry about lvalue-to-reference conversion: 返回一个限定类型的函数会发生类似的过程,这样做的好处是我们不需要担心左值到参考的转换:

const int g();
static_assert(std::is_same<decltype(g()), int>::value, "!!!");

The type of f() is int ; f()的类型是int ; its value category is lvalue. 它的价值类别是左值。 You can demonstrate this fact: 你可以证明这个事实:

int& f();
static_assert(std::is_same<int&,decltype((f()))>::value,"EXPLODE");

per C++11 §7.1.6.2 [dcl.type.simple]/4 "...if e is an lvalue, decltype(e) is T& , where T is the type of e ". 每个C ++11§7.1.6.2[dcl.type.simple] / 4“......如果e是左值,则decltype(e)T& ,其中Te的类型。

Example code: 示例代码:

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;
}

Output with Visual C++ 12.0 and with MinGW g++ 4.7.2: 使用Visual C ++ 12.0和MinGW g ++ 4.7.2输出:

Function calls foo versus bar: 函数调用foo与bar:
true 真正
false

lvalue versus ref: 左值与参考值:
false
true 真正

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从调用表达式中获取函数的类型? - How can I get the function's type from a call expression? 将函数调用表达式传递给 noexcept 有什么意义? - What is point in passing a function call expression into noexcept? 定义函数时,lambda函数/表达式是什么类型的? - When defining a function, what type is a lambda function/expression? “表达式必须具有类类型”错误,尝试调用类函数 - “Expression must have class type” Error, trying to call a class function 函数调用给我错误表达式必须具有类类型 - Function call is giving me the error expression must have class type 在我的主要 function 中,我遇到了一些类型为“在 'int' 之前的预期主表达式”类型的错误。 怎么了? - I've got some errors of type “expected primary-expression before 'int' ”in my main function. What's wrong? 这种间接的 function 调用有什么好处? - What's the advantage of this indirect function call? 在函数调用中使用多个星号有什么用? - What's the use of multiple asterisks in the function call? 临时对象的生命周期延长:包含函数调用的完整表达式是什么? - Lifetime extension of temporary objects: what is the full expression containing a function call? 这个 lambda function 的实际类型是什么? - What's the actual type in this lambda function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM