gpt4 book ai didi

c++ - VS2008 SP1 : No appropriate default constructor available when pushing a pair into vector

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:05:24 25 4
gpt4 key购买 nike

背景

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

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

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

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

用法

试图向后推:

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

编译错误(VS2008 SP1)

以下error 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 documentation说它应该接受可复制分配和可复制构造的对象:

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

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

问题

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

最佳答案

长话短说

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

说明

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

引述如下(为简洁起见,强调我的意思):

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

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.

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>.

...

As workarounds, you can:

  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,则提供默认构造函数:

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

关于c++ - VS2008 SP1 : No appropriate default constructor available when pushing a pair into vector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51282596/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com