VS2008 SP1:将一对推入向量时没有合适的默认构造函数

时间:2018-07-11 10:00:39

标签: c++ visual-studio-2008 c++03 compiler-bug

背景

Foo具有用户声明的构造函数,因此没有implicitly-declared default constructor

struct Foo {
    Foo(...) {...}
};

然后在std::vector的{​​{1}}中使用它,如下所示:

std::pair

用法

尝试回退向量:

std::vector<std::pair<std::string, Foo> >

编译错误(VS2008 SP1)

以下error C2512

std::vector<std::pair<std::string, Foo> > v;
v.push_back(std::make_pair(std::string("some string"), Foo(...)));

注释

  • std::vector documentation说它应该接受可分配复制和可复制复制的对象:

      

    T 必须满足 CopyAssignable CopyConstructible 的要求(直到C ++ 11)。

  • 使用gcc和VS2008(SP1之前的版本)可以很好地编译代码。

问题

是什么导致错误? VS2008 SP1中有错误吗?如果是,什么解决方法?

1 个答案:

答案 0 :(得分:1)

TL; DR

这是VS 2008 SP1中的错误。最简单的解决方法是在检测到VS 2008 SP1时提供默认的构造函数。

说明

经过一些研究,我发现thread on msdn forum描述了类似的情况。该线程包含Microsoft员工的答案,该答案提供了清晰的解释。

这是报价(为简洁起见,简称我的缩写):

  

感谢您报告此错误...   这是在Visual C ++ 2008功能包中引入的,该功能包是   合并到SP1中。

     

我们在此处使用了OR(在元组的'Foo' : no appropriate default constructor available ...\Microsoft Visual Studio 9.0\VC\include\utility(43): while compiling class template member function 'std::pair<_Ty1,_Ty2>::pair(void)' 中使用了OR)   故意地。我们想将_Move_operation_category视为   快速交换(是的)。不幸的是,我们忘记了   Swaptimization需要一个默认的构造函数,以及该对/元组   允许用户定义的类型潜入。(例如pair<int, string>   或vector<T>,即使shared_ptr<T>没有默认的构造函数,   向量或T。)显然,这很糟糕。

     

此一致性错误有一线希望:至少此错误   告诉您shared_ptr会变慢   比vector<pair<foo, wstring> >

     

...

     

作为解决方法,您可以:

     
      
  1. 给foo一个默认的构造函数。这将快速交换wstring和普通交换foo。
  2.   
  3. 给foo一个默认的构造函数,以及一个可以通过ADL获取的swap()实现。这将快速交换两个wstring   还有foo。
  4.   
  5. 写一对。这将禁用“ Swaptimization”。
  6.   
  7. 使用vector<wstring>。这将快速交换vector<pair<shared_ptr<foo>, wstring> >shared_ptr。当然,您现在正在做更多动态   内存分配,因此仅在某些情况下才需要   情况。
  8.   
     

请注意,当我们获得移动语义时,此交换机制将是   消除,这将是非常棒的。

解决方法

考虑了变通办法后,我选择了#1:如果检测到VS2008 SP1,则提供默认的构造函数:

wstring