简体   繁体   English

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

[英]Why return-type 'cv' is ignored?

At least in 'Clang' & 'GCC'. 至少在'Clang'和'GCC'中。 Here is an example: 这是一个例子:

char *const InString(char *const p) {

    return gets(p);
}

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

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

As most of you probably knows in the second line of ' main' we are bounding the return-value temporary ('prvalue') into an 'rvalue reference' thus extending its life time. 正如大多数人可能知道的那样,在' main'的第二行中,我们将返回值临时('prvalue')绑定到'右值参考',从而延长其生命周期。 So my question is what is happening here - is 'cv' for return-values really ignored and if so where in the standard this is written or else how 'char *const &&' is converted to 'char * &&' ? 所以我的问题是这里发生了什么 - 返回值的'cv'真的被忽略了,如果是这样,那么在标准中这是写的,或者'char *const &&'如何转换为'char * &&'

*Need ISO C++ standard qualification. *需要ISO C ++标准资格。

EDIT: The thing is that before 'C++ 11' you weren't allowed to modify the return-value whatsoever because 'rvalues' weren't introduced and also because something like: 编辑:事情是,在'C ++ 11'之前你不允许修改返回值,因为'rvalues'没有被引入,也是因为:

InString(arr) = nullptr;

Was meaningless. 毫无意义。 However now you can extend the 'return-value' life-time and so modifying it becomes possible: 但是现在你可以扩展'返回值'的生命周期,因此可以修改它:

auto &&refRetVal = InString(arr);

refRetVal = nullptr;

From this it comes that the 'const' return 'cv' can be useful. 由此可见,'const'返回'cv'非常有用。 If the return-type of 'InString' above is 'constant' then the second assignment to 'nullptr' will be illegal. 如果上面的'InString'的返回类型是'常量',则第二次赋值为'nullptr'将是非法的。

After considering the quote mentioned by @dyp, which is [expr]/6: 在考虑了@dyp提到的引用之后,这是[expr] / 6:

If a prvalue initially has the type “ cv T ,” where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis . 如果prvalue最初具有类型“ cv T ”,其中T是cv-非限定的非类非数组类型, 则在进行任何进一步分析之前将表达式的类型调整为T

The conclusion is rather simple: As the expression InString(..) is a prvalue, the type of InString(..) (which is the initializer of the reference) is simply adjusted to char* , which is clearly reference compatible to the target type of the reference (also char* ). 结论很简单:由于表达式InString(..)是一个prvalue, InString(..)的类型(它是引用的初始化器)只是简单地调整为char* ,这显然与目标兼容引用的类型(也是char* )。 In other words, the const you added is simply ignored when determining the type of the function call expression (but it is not ignored when looking at the function type itself!). 换句话说,在确定函数调用表达式类型时,简单地忽略了您添加的const (但在查看函数类型本身时不会忽略它!)。

However, for scalar prvalues, references never bind directly to the initializer expression, but a temporary is initialized and the reference bound to it: 但是,对于标量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

The cv-qualifier in return types is ignored only of the very first level, so int const foo() equals int foo() but int const &foo() does not equal int &foo() . 返回类型中的cv限定符仅在第一级忽略,因此int const foo()等于int foo()int const &foo()不等于int &foo()

In your case, your function char *const InString() is equivalent to char *InString() . 在您的情况下,函数char *const InString()等效于char *InString()

And about the binding of the char *&&str = InString(arr) . 关于char *&&str = InString(arr)的绑定。 The return of the function is a r-value (a temporary), and str is an r-value reference, so this is expected. 函数的返回值是r值(临时值), str是r值引用,因此这是预期的。 Of course, the lifetime of the temporary is extended to the scope of the reference. 当然,临时的生命周期延伸到参考范围。

BTW, your code, compiled with -Wextra gives in CLang++: 顺便说一句,您的代码是用-Wextra编译的,在CLang ++中给出:

warning: 'const' type qualifier on return type has no effect [-Wignored-qualifiers] 警告:返回类型的'const'类型限定符没有效果[-Wignored-qualifiers]

And in G++: 在G ++中:

warning: type qualifiers ignored on function return type [-Wignored-qualifiers] 警告:在函数返回类型[-Wignored-qualifiers]上忽略类型限定符

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM