Linux vs Windows std::map 赋值构造函数(为什么会有这样的区别?)
Linux vs Windows std::map assignment constructors (Why such a difference?)
我在用Linux Ubuntu编写的C++应用程序中目睹了一些意外的行为。我会用参数构造一个对象,然后使用赋值运算符将该对象的副本放入 std::map 中。我写了一个简单的程序来演示这种情况......
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Foo
{
public:
Foo(void) : _x(0)
{
cout << "Default" << endl;
}
Foo(int a) : _x(a)
{
cout << "Param" << endl;
}
Foo(Foo const &foo) :
_x(foo._x)
{
cout << "Copy" << endl;
}
Foo& operator=(Foo const &foo)
{
cout << "Assignment" << endl;
if (this != &foo)
{
_x = foo._x;
}
return *this;
}
int get(void)
{
return _x;
}
private:
int _x;
};
int main(int argc, char *argv [])
{
std::map<int, Foo> foos;
Foo a_foo(10);
foos[100] = a_foo;
return 0;
}
在这里,我只是打印出哪个构造函数/运算符以什么顺序被调用,这样我可以看到构造和赋值在"main"函数中是如何工作的。
当我在 Windows 中运行它时,我得到了预期的输出......
参数
违约
分配
当我在 Linux 中运行它时,我得到以下输出...
参数
违约
复制
复制
分配
为什么有两个额外的复制构造函数?创建这么多次对象似乎效率很低?
谢谢!
答案就在stl_map.h。它的行为取决于您是否使用 C++11 支持进行编译。 如果这样做,则 STL 可以利用移动语义来避免不必要的复制。VC++ 默认使用新的语言功能,但如果使用 g++ 或 clang,则需要习惯在 4.2 中使用 -std=c++0x
标志,或者在较新版本中使用 -std=c++11
标志。
设置-std=c++11
后,使用 g++4.8 的输出为:
Param
Default
Assignment
编辑:非常感谢您为我澄清,我假设这是移动语义是不正确的。我把这个答案留在原地,以引导用户找到这个更好的答案。
相关文章:
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- std::is_convertible 和 std::convertible_to 之间的区别(在实践中)?
- std::enable_if 和 std::enable_if_t 有什么区别?
- "owned pointer"和 std::shared_ptr 的"stored pointer"有什么区别?
- std::ranges::begin 和 std::begin 有什么区别?
- std::stable_partition() 和 std::p artition() 有什么区别?
- std::fabs(a * b) 和 std::fabs(a) * std::fabs(b) 之间的区别
- 普通的右值引用和 std::forward 返回的引用有什么区别?
- std::tie 和 std::forward_as_tuple 有什么区别
- printf() 和 std::cout 在指针方面的区别
- malloc 和 calloc 与 std::string 之间的区别
- std::random_device和std::mt19937_64之间有什么区别
- 使用 std::move 将参数传递给函数,如果该参数声明为按值传递或使用移动操作数 &&,是否有区别?
- 打印一个带有静态 int 的函数,有一个 std::cout 和多个 std::cout 有什么区别?
- std::bit_cast 和 std::start_lifetime_as 之间有什么有用的区别吗?
- Python的bisect.bisect_left和C++的std::upper_bound的区别
- 互锁变量访问(在布尔值上)和 std::atomic_flag 之间的区别
- std::string [] 运算符和 at() 之间的区别
- Memmove和C ++ 11有什么区别 std::move.