VS2008 SP1:将一对推入向量时没有合适的默认构造函数可用 [英] VS2008 SP1: No appropriate default constructor available when pushing a pair into vector

查看:29
本文介绍了VS2008 SP1:将一对推入向量时没有合适的默认构造函数可用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Class Foo 具有用户声明的构造函数,因此没有 隐式声明的默认构造函数:

Class Foo has user-declared constructor and thus no implicitly-declared default constructor:

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

然后在std::pairstd::vector中使用如下:

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

用法

尝试向后推向量:

Usage

Attempting to push back in the vector:

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

编译错误(VS2008 SP1)

以下错误C2512:

'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)'

注意事项

  • std::vector 文档 表示它应该接受可复制分配和可复制构造的对象:

    Notes

    • std::vector documentation says it should accept copy-assignable and copy-constructible objects:

      T 必须满足 CopyAssignableCopyConstructible 的要求(直到 C++11).

      T must meet the requirements of CopyAssignable and CopyConstructible (until C++11).

    • 代码在 gcc 和 VS2008(SP1 之前)下编译得很好.

    • The code compiles just fine with gcc and VS2008 (pre SP1).

      是什么导致了错误?VS2008 SP1 是否有错误?如果是,有哪些解决方法?

      What is causing the error? Is there a bug in VS2008 SP1? If yes, what are the work-arounds?

      推荐答案

      TL;DR

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

      TL;DR

      This is a bug in VS 2008 SP1. Simplest possible work-around is providing a default constructor when VS 2008 SP1 is detected.

      在做了一些研究之后,我发现了 msdn 论坛上的帖子 描述了类似的情况.该线程包含来自 Microsoft 员工的回答,其中提供了明确的解释.

      After doing some research I found the thread on msdn forum describing similar situation. The thread contains an answer from Microsoft employee which provides clear explanation.

      这是引用(为简洁起见缩短,强调我的):

      Here's the quote (shortened for brevity, emphasis mine):

      感谢您报告此错误...这是在 Visual C++ 2008 Feature Pack 中引入的,它是并入 SP1.

      Thanks for reporting this bug ... This was introduced in the Visual C++ 2008 Feature Pack, which was incorporated into SP1.

      我们在这里使用了 OR(以及元组的_Move_operation_category)故意地.我们想将 pair 视为可快速交换(确实如此).不幸的是,我们忘记了Swaptimization 需要一个默认构造函数,以及那个对/元组允许用户定义的类型潜入.(使用类似 vectorshared_ptr,即使 T 没有默认构造函数,vector 或 shared_ptr 可以.)显然,这是我的错.

      We used OR here (and in tuple's _Move_operation_category) intentionally. We wanted to consider pair<int, string> to be fast-swappable (which it is). Unfortunately, we forgot that the Swaptimization requires a default constructor, and that pair/tuple allow user-defined types to sneak in. (With something like vector<T> or shared_ptr<T>, even if T doesn't have a default constructor, the vector or shared_ptr does.) Clearly, this was my bad.

      这个一致性错误有一线希望:至少是这个错误让你知道 vector> 会更慢比 vector.

      There's a silver lining to this conformance bug: at least this error is letting you know that vector<pair<foo, wstring> > will be slower than vector<wstring>.

      ...

      作为解决方法,您可以:

      1. 给 foo 一个默认构造函数.这将快速交换 wstring 和一般交换 foo.
      2. 给 foo 一个默认构造函数,以及一个可以通过 ADL 获取的 swap() 实现.这将快速交换 wstring和 foo.
      3. 编写您自己的配对.这将禁用Swaptimization".
      4. 使用vector, wstring>;>.这将快速交换 shared_ptrwstring.当然,现在你做的更有活力内存分配,因此这仅在某些情况下是可取的情况.
      1. Give foo a default constructor. This will fast-swap the wstring and general-swap the foo.
      2. Give foo a default constructor, and a swap() implementation that can be picked up through ADL. This will fast-swap both the wstring and the foo.
      3. Write your own pair. This will disable the "Swaptimization".
      4. Use vector<pair<shared_ptr<foo>, wstring> >. This will fast-swap the shared_ptr and wstring. Of course, now you're doing more dynamic memory allocations, so this is desirable only in certain circumstances.

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

      Note that when we get move semantics, this swap machinery will be eliminated, which is going to be so awesome.

      解决办法

      在考虑解决方法后,我选择了 #1:如果检测到 VS2008 SP1,则提供默认构造函数:

      A work-around

      After considering the work-arounds I went with #1: providing a default constructor if VS2008 SP1 is detected:

      struct Foo {
          Foo(...) {...}
      #if _MSC_FULL_VER == 150030729 // Visual Studio 2008, SP1
          Foo() {} //<- work-around for VS2008 SP1 bug
      #endif
      };
      

      这篇关于VS2008 SP1:将一对推入向量时没有合适的默认构造函数可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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