为什么忽略返回类型'cv'?

AnA*_*ons 3 c++ const return-type language-lawyer c++11

至少在'Clang'和'GCC'中.这是一个例子:

char *const InString(char *const p) {

    return gets(p);
}

int main()
{
    static char arr[260];

    char * &&str = InString(arr); //compiles without error - what??????
}
Run Code Online (Sandbox Code Playgroud)

正如大多数人可能知道的那样,' main'我们将返回值临时值('prvalue')限制为'右值参考', 从而延长其生命周期.所以我的问题是这里发生了什么 - 返回值的'cv'真的被忽略了,如果是这样,那么在标准中这是写的还是如何'char *const &&'转换成'char * &&'

*需要ISO C++标准资格.

编辑:事情是,在'C++ 11'之前你不允许修改返回值,因为'rvalues'没有被引入,也是因为:

InString(arr) = nullptr;
Run Code Online (Sandbox Code Playgroud)

毫无意义.但是现在你可以扩展'返回值'的生命周期,因此可以修改它:

auto &&refRetVal = InString(arr);

refRetVal = nullptr;
Run Code Online (Sandbox Code Playgroud)

由此可见,'const'返回'cv'非常有用.如果上面的'InString'的返回类型是'常量',则第二次赋值为'nullptr'将是非法的.

Col*_*mbo 8

在考虑了@dyp提到的引用之后,这是[expr]/6:

如果prvalue最初具有类型" cv T ",其中T是cv非限定的非类非数组类型,T在进行任何进一步分析之前调整表达式的类型.

结论很简单:由于表达式InString(..)是一个prvalue,InString(..)(参考的初始化器)的类型只是简单地调整为char*,这显然是参考的目标类型(也是char*)的参考.换句话说,const在确定函数调用表达式类型时,简单地忽略了您添加的内容(但在查看函数类型本身时不会忽略它!).

但是,对于标量prvalues,引用永远不会直接绑定到初始化表达式,但初始化临时并绑定引用:

int&& i = 4; // Temporary initialized with 4 and bound to i

int const f();
int&& ref = f(); // Initializer expression has type int - same as above
Run Code Online (Sandbox Code Playgroud)

  • 这确实是我在C++中遇到的最奇怪的规则之一.我想我在尝试绑定到推导出类型的左值引用时已经学会了它:`auto&x = g();`如果`g`返回一个const非类类型,则不起作用. (2认同)