gpt4 book ai didi

c++ - C++ 标准是否为编译器指定了 STL 实现细节?

转载 作者:可可西里 更新时间:2023-11-01 15:51:09 25 4
gpt4 key购买 nike

在写 this 的答案时问题 我遇到了一个有趣的情况——这个问题演示了这样一种情况,即有人想将一个类放入 STL 容器中,但由于缺少复制构造函数/移动构造函数/赋值运算符而未能这样做。在这种特殊情况下,错误是由 std::vector::resize 触发的。我制作了一个快速片段作为解决方案,并看到另一个答案提供了一个移动构造函数,而不是我所拥有的赋值运算符和复制构造函数。有趣的是,另一个答案没有在 VS 2012 中编译,而 clang/gcc 对这两种方法都很满意。

首先:

// Clang and gcc are happy with this one, VS 2012 is not
#include <memory>
#include <vector>

class FooImpl {};

class Foo
{
std::unique_ptr<FooImpl> myImpl;
public:
Foo( Foo&& f ) : myImpl( std::move( f.myImpl ) ) {}
Foo(){}
~Foo(){}
};

int main() {
std::vector<Foo> testVec;
testVec.resize(10);
return 0;
}

第二个:

// Clang/gcc/VS2012 are all happy with this
#include <memory>
#include <vector>

using namespace std;
class FooImpl {};

class Foo
{
unique_ptr<FooImpl> myImpl;
public:
Foo()
{
}
~Foo()
{
}
Foo(const Foo& foo)
{
// What to do with the pointer?
}
Foo& operator= (const Foo& foo)
{
if (this != &foo)
{
// What to do with the pointer?
}
return *this;
}
};

int main(int argc, char** argv)
{
vector<Foo> testVec;
testVec.resize(10);
return 0;
}

为了了解发生了什么,我查看了 VS 2012 中的 STL 源代码,发现它确实在调用移动赋值运算符,这就是我的示例工作的原因(我没有可访问的 Linux 机器来了解发生了什么on in in clang/gcc) 而另一个没有,因为它只有移动复制构造函数。

因此这产生了以下问题 - 编译器能否自由决定如何实现 STL 方法(在本例中为 std::vector::resize),因为完全不同的实现可能会导致不可移植的代码?或者这只是一个 VS 2012 错误?

最佳答案

Visual C++ 2012 无法 auto-generate the move constructor and the move assignment operator .一个只会被修复的缺陷 in the upcoming 2015 version .

您可以通过向 Foo 添加显式移动赋值运算符来编译您的第一个示例:

#include <memory>
#include <vector>

class FooImpl {};

class Foo
{
std::unique_ptr<FooImpl> myImpl;
public:
Foo( Foo&& f ) : myImpl( std::move( f.myImpl ) ) {}
// this function was missing before:
Foo& operator=( Foo&& f) { myImpl = std::move(f.myImpl); return *this; }
Foo(){}
~Foo(){}
};

int main() {
std::vector<Foo> testVec;
testVec.resize(10);
return 0;
}

详见 ikh's answer ,标准实际上不需要移动赋值运算符。 vector<T>::resize()的相关概念是MoveInsertableDefaultInsertable ,您的初始实现仅使用移动构造函数就可以满足这一要求。

VC 的实现也需要这里的 move 分配是一个不同的缺陷,它已经在 VS2013 中修复。

感谢ikhdyp感谢他们在这个问题上的深刻贡献。

关于c++ - C++ 标准是否为编译器指定了 STL 实现细节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30935840/

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