Linux vs Windows std :: map赋值构造函数(为什么会有这样的区别?) [英] Linux vs Windows std::map assignment constructors (Why such a difference?)

查看:720
本文介绍了Linux vs Windows std :: map赋值构造函数(为什么会有这样的区别?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目睹了在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<< 复制<< endl
}

Foo& operator =(Foo const& foo)
{
cout< 作业<< 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;
}

这里我只是打印出哪个构造函数/我可以看到如何在主功能的构造和分配工作。



当我在Windows中运行时,我得到我的预期输出...



Param

默认

赋值



当我在Linux中运行这个命令时,我得到以下输出...



参数

默认

复制

复制

分配



为什么有两个额外的复制构造函数?这么多次创建对象似乎效率很低?



谢谢!

解决方案

答案在于stl_map.h。它的行为取决于是否使用C ++ 11编译支持。 默认情况下,VC ++使用新的语言功能,但如果你使用g ++或clang,你需要习惯使用 -std = c ++ 0x 在较新版本中,标记为4.2或 -std = c ++ 11 b
$ b

使用 -std = c ++ 11 设置g ++ 4.8的输出是:

  Param 
默认
分配

编辑:非常感谢您向我澄清,我假设这是向下移动语义是不正确的。我要留下此答案,以引导用户更好的答案


I was witnessing some unexpected behavior in a C++ application I am writing in Linux Ubuntu. I would construct an object with parameters and then put a copy of that object into a std::map using the assignment operator. I wrote a simple program to demonstrate this situation...

#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;
}

Here I am just printing out which constructor/operator gets called in what order so I can see how the construction and assignment works in the "main" function.

When I run this in Windows I get my expected output...

Param
Default
Assignment

When I run this in Linux I get the following output...

Param
Default
Copy
Copy
Assignment

Why are the two extra copy constructors there? It seems very inefficient to create the object so many times?

Thanks!

解决方案

The answer lies in stl_map.h. Its behaviour depends on whether you compile with C++11 support or not. If you do then the STL can take advantage of move semantics to avoid unnecessary copying. VC++ uses the new language features by default but if you use g++ or clang you need to get used to using the -std=c++0x flag in 4.2 or -std=c++11 in newer versions.

With -std=c++11 set the output with g++4.8 is:

Param
Default
Assignment

Edit: Thank you very much for clarifying for me that my assumption that this was down to move semantics was incorrect. I'm leaving this answer in place to direct users to this better one.

这篇关于Linux vs Windows std :: map赋值构造函数(为什么会有这样的区别?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆