在下面的这段代码中,我在一个结构中有std::map
。然后我只是将结构的一个实例分配给其他人。请注意,该结构没有赋值运算符。在这种情况下,我是否应该调用map的赋值运算符,或者编译器只是浅层副本内存包含结构?
int _tmain(int argc, _TCHAR* argv[])
{
struct vectstruct
{
std::map<int, double> mymap;
};
vectstruct vs1, vs2;
vs1.mymap[7] = 54.321;
vs2 = vs1; // Should call assignment operator of map vs2.mymap
vs1.mymap[7] = 65.432;
return 0;
}
我尝试使用Microsft Visual Studio,在程序结束时,我发现vs2.mymap[7]
的值仍然符合预期54.321
。但我想知道C ++标准是正确的还是我需要编写vectstruct
的赋值运算符,其中我明确地会调用map的赋值运算符?
答案 0 :(得分:2)
作为一种风格问题,您应该在main
之外声明和定义您的类型。
也就是说,如果你没有提供一个拷贝赋值操作符,编译器会隐式为你创建一个,而隐式的只会进行逐元素复制赋值。在这种情况下,隐式的看起来像:
vectstruct& operator=(const vectstruct& rhs) {
mymap = rhs.mymap;
return *this;
}
对于std::map
,作业需要完整复制,不需要参考,所以在代码的最后你应该期望:
vs2.mymap[7] == 54.321 // to the extent that equality of doubles is a thing
vs1.mymap[7] == 65.432
*在某些情况下,编译器无法创建一个隐式赋值运算符,它基本上归结为具有不可复制成员的对象。例如,引用或unique_ptr
。
答案 1 :(得分:1)
默认operator=
将执行逐个成员的副本,这是您所期望的。 I. e。它将为您的struct的每个数据成员调用operator=
。反过来,std::map
实现了operator=
,所以一切都会像魅力一样起作用。不需要自己编写相同的操作符来膨胀您的代码。