在此代码中:
#include <iostream>
int main(void)
{
std::string {} = "hi";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这种类型的声明在 C++ 中有效。参见《Godbolt》。
作为信息,我测试了这个程序从c++11到c++20标志,因为扩展初始值设定项从以后可用c++11。
C++ Primer 5th:
(代码也来自书中,这里提供了99%的上下文)
#include <string>
using namespace std;
int main()
{
//no error
string s1 = "123", s2 = "aaaa";
s1 + s2 = "wow";
auto a = (s1 + s2).find("a");
}
Run Code Online (Sandbox Code Playgroud)
在新标准(这里是C++ 11)之前,没有办法阻止这种使用.为了保持向后兼容性,库类继续允许赋值给rvalues,但是,我们可能希望在我们自己的类中阻止这种用法.在这种情况下,我们想强制左手操作数(即
this点的对象)为左值.
什么向后兼容性需要为rvalues分配?
顺便说一句,我也很好奇为什么s1 + s2 = "wow"被允许但int i = 3, j = 4; i + j = 7;不允许.(因为它密切相关,我选择不打开另一个问题)
为什么这段代码会编译?我认为ctor返回的rvalues不在内存中,因此不能用作左值.
#include <iostream>
#include <vector>
class Y {
public :
explicit Y(size_t num = 0)
: m_resource {std::vector<int>(num)}
{
}
std::vector<int> m_resource;
};
int main(int argc, const char * argv[]) {
Y(1) = Y(0); // WHAT?!?
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我和我的 C++ 同事遇到了一个奇怪的结构:
struct A { int i; };
void foo(A const& a);
int main() {
foo(A() = A{2}); // Legal
}
Run Code Online (Sandbox Code Playgroud)
这个A() = A{2}表达式完全把我们弄糊涂了,因为它似乎正在分配A{2}给一个临时的、默认构造的对象。但是在编译器资源管理器中看到它(https://gcc.godbolt.org/z/2LsfSk)。它似乎是一个法律声明(由 GCC 9 和 Clang 9 支持),如下声明:
struct A { int i; };
int main() {
A() = A{2};
auto a = A() = A{3};
}
Run Code Online (Sandbox Code Playgroud)
因此,在某些情况下,它似乎A()是一个左值。还是这里发生了其他事情?希望得到一些解释,最好是对 C++17 标准的引用。
更新:@Brian 发现这是赋值给右值的重复:为什么编译?. 但如果有人能在 C++ 标准中找到合适的参考,我将不胜感激。