将返回的左值隐式处理为右值
Implicitly treating returned lvalue as rvalue
12.8复制和移动类对象[class.copy]§31和§32说:
在具有类返回类型的函数中的返回语句中,当表达式是与函数返回类型具有相同cv不合格类型的非易失性自动对象(函数或catch子句参数除外)的名称时,可以通过将自动对象直接构造到函数的返回值中来省略复制/移动操作
当满足或将满足省略复制操作的标准时,除非源对象是函数参数,并且要复制的对象是由左值指定的,否则首先执行重载解析以选择复制的构造函数,就好像对象是由右值指定的一样。
因此我们可以写:
unique_ptr<int> make_answer()
{
unique_ptr<int> result(new int(42));
return result; // lvalue is implicitly treated as rvalue
}
然而,我注意到g++4.6.3也接受而不是名称的左值,例如:
return (result);
return *&result;
return true ? result : result;
相比之下,return rand() ? result : result;
不起作用。编译器的优化器是否干扰了语言语义?在我解释标准时,return (result);
不应该编译,因为(result)
不是一个名称,而是一个带括号的表达式。我是对还是错?
关于带括号的表达式[√]
当谈到带括号的表达式时,你错了,当返回并且只包含可移动对象的名称时,它不应该触发移动 带括号的表达式是其类型和值与所附表达式的值相同。这个括号的存在不会影响表达式是否为左值除非另有说明,带括号的表达式可以在与可以使用带括号表达式的上下文完全相同的上下文中使用,并且具有相同的含义。 我现在更仔细地研究了这个标准,它没有说常量条件表达式与如果只有";返回"表达式就会被写入。 在C99中,明确指出 尽管我们都同意使用 当然,表达式包含一个合适的名称,但它不仅仅是这样。
5.1.1.1概述【expr.prim.General】
关于constexpr条件运算符[╳]
我解释关于常量表达式和编码运算符的标准的方式是,return true ? result : result
的使用表现良好,因为它是一个常量表达式,因此等价于返回结果true ? <expr1> : <expr2>; // this is not the same as just writing <expr1>;
关于返回*&结果[╳]
*&result
是确切的等价于编写result
,而C++规范中并非如此。*&result
确实会产生与result
相同的左值,但根据标准*&result
(当然)不是"的表达式;表达式是非易失性自动对象"的名称。总而言之
return result; // #1, OK
return (result); // as described earlier, OK
return true ? result : result; // as described earlier, ill-formed
return rand () ? result : result; // as described earlier, ill-formed
return *&result; // as described earlier, ill-formed
除非另有说明,带圆括号的表达式等效于其未带圆括号表达式(例如,在ADL规则中执行,或者在另一个示例中通过decltype执行)。当某些东西以这种方式不等价时,有时可能会很棘手(例如,ADL规则没有明确提到"未加括号",但它们使用了明确的语法非词尾和明确表示parens不被视为等价的例子)。
对于其他问题:是的,GCC直接对AST进行了一些优化,使其接受各种无效程序,如以下
int a = 42;
int *p = 0 * a;
- 使用返回对象的函数处理错误
- 如何使用从处理程序调度的最终回调将响应异步返回给调用方on_read?
- 如何在 c++ 窗口中将参数和返回的退出值传递到批处理文件/从批处理文件获取返回的退出值
- 处理模板函数包装中的void返回
- 使用std::tie进行类似golang的错误处理,同时返回结果,是否有缺点?(C++11)
- 对clang、gcc和icc中开关枚举类返回的处理一致
- 我可以让返回类型自动处理具有相同签名但捕获不同内容的 lambda 吗?
- cudaMemcpyToSymbol只是挂起,永远不会返回.GPU 处理速度为 100%.代码在 K40 上工作正常,但
- 套接字 read() 函数在处理隧道时有时从不返回 0
- 在对原始字符串进行一些处理后返回(或转换)原始字符串
- 创建一个函数,如果元素在unordered_set中,则返回 true,如何处理模板
- 如何处理不保证返回任何内容的函数
- C :ScopeGuard vs返回支票和异常处理
- 返回处理数组的INT功能
- 尝试阅读文件时,如何处理马车返回线供稿
- Qjson 处理返回的 ojbect 数组
- 如何编写一个C++函数,根据处理返回不同类型的std::list
- c++错误处理返回值错误返回
- 处理返回void的方法和返回值的方法
- Boost Lambda/Phoenix-如何处理返回另一个Lambda的Lambda