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

时间:2015-01-15 18:46:50

标签: c++ c++11 const language-lawyer return-type

至少在'Clang'和“海湾合作委员会”。这是一个例子:

char *const InString(char *const p) {

    return gets(p);
}

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

    char * &&str = InString(arr); //compiles without error - what??????
}

正如大多数人可能知道的第二行'main'我们将返回值临时值('prvalue')绑定到'右值参考',从而延长了它的寿命时间。所以我的问题是这里发生了什么 - 返回值的'cv'是否真的被忽略了,如果是这样,标准中写的是什么,或者'char *const &&'如何转换为'char * &&'

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

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

InString(arr) = nullptr;

毫无意义。但是现在您可以延长“返回值”的生命周期,因此可以对其进行修改:

auto &&refRetVal = InString(arr);

refRetVal = nullptr;

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

2 个答案:

答案 0 :(得分:8)

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

  

如果prvalue最初的类型为“ cv T,”其中T是   cv-unqualified non-class,non-array type,的类型        在进行任何进一步分析之前,将表达式调整为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

答案 1 :(得分:1)

返回类型中的 cv-qualifier 仅在第一级忽略,因此int const foo()等于int foo()int const &foo()不等于{{1} }}

在您的情况下,您的功能int &foo()相当于char *const InString()

关于char *InString()的绑定。函数的返回值是r值(临时值),char *&&str = InString(arr)是r值引用,因此这是预期的。当然,临时的生命周期延伸到参考范围。

BTW,用str编译的代码在CLang ++中给出:

  

警告:返回类型的'const'类型限定符无效[-Wignored-qualifiers]

在G ++中:

  

警告:在函数返回类型[-Wignored-qualifiers]

上忽略类型限定符