Cha*_*l72 20 c++ move-constructor move-semantics c++11 std-pair
假设你想利用移动语义,但你的一个可移动类需要成为一部分std::pair.目的是创建一个函数,该函数返回一个std::pair可被视为右值并转发的函数.
但我无法看到如何做到这一点,除非对其std::pair自身进行内部更改,以使其了解移动语义.
请考虑以下代码:
struct Foo
{
Foo() { }
Foo(Foo&& f) { }
private:
Foo(const Foo& f) { } // do not allow copying
};
int main()
{
Foo f;
std::pair<Foo, int> res = std::make_pair(f, 10); // fails due to private copy constructor
}
Run Code Online (Sandbox Code Playgroud)
问题是std::make_pair,除了std::pair构造函数本身之外,还需要两个对象并尝试制作它们的内部副本.这导致它尝试并调用复制构造函数.但在我的例子中,我希望能够将新对移动到res,并确保不会制作副本.我认为除非std::pair自己在内部定义了以下构造函数,否则这是不可能的:
pair(T1&& t1, T2&& t2) : first(std::move(t1)), second(std::move(t2))
Run Code Online (Sandbox Code Playgroud)
但它没有,至少在我使用的编译器上没有(gcc 4.3.2).这可能是因为我的编译器是简单地外的日期,而事实上新版本将拥有这一举动感知构造.但是我对移动语义的理解目前有点不稳定,所以我不确定我是否只是在这里忽略了一些东西.那么,我是否正在努力实现,而不是实际重新实现std::pair?或者我的编译器是否已过时?
Jam*_*lis 19
但是,这不是std::pair将被调用的构造函数.该std::pair移动构造函数将被调用,而移动构造函数应该做的正是你所期望的(N3126 20.3.5.2/6):
template<class U, class V> pair(pair<U, V>&& p);
Run Code Online (Sandbox Code Playgroud)
效果:构造函数首先使用
std::move(p.first)和第二个初始化std::move(p.second).
然而,你的榜样应该失败,因为std::make_pair(f, 10);,f是一个左值,需要明确moveð,否则将被复制.以下应该有效:
std::pair<Foo, int> res = std::make_pair(std::move(f), 10);
Run Code Online (Sandbox Code Playgroud)