删除元组成员的复制构造函数导致错误
Deleted copy constructor of tuple member cause error
这段代码
#include <tuple>
struct Foo
{
Foo(const int& value):value_(value){}
//Foo(const Foo&)=delete; // delete copy constructor
int value_;
};
int main()
{
std::tuple<Foo> tup(std::move(Foo(1)));
return 0;
}
工作正常,但如果删除 Foo
复制构造函数,它将失败并出现以下编译错误:使用已删除的函数 Foo::Foo(const Foo&)
.
但是,既然我明确告诉对象可以移动,为什么 std::tuple
构造函数使用 Foo
复制构造函数而不是它的移动构造函数?如何强制构建 std::tuple
移动 Foo
实例而不是复制它?
But, since I am telling explicitly that the object can be moved,
不,您是在告诉编译器您想要移动对象。这不是一回事。
why the std::tuple
constructor uses the Foo
copy constructor instead of its moving constructor?
因为删除复制构造函数时隐含的移动构造函数不存在,所以不能使用
How can I enforce the std::tuple to be constructed moving the Foo instance instead of copying it?
要么不删除复制构造函数,要么也定义一个移动构造函数:
struct Foo
{
Foo(const int& value):value_(value){}
Foo(const Foo&)=delete; // delete copy constructor
Foo(Foo&&)=default;
int value_;
};
N.B。这里的std::move
完全没用:
std::tuple<Foo> tup(std::move(Foo(1)));
std::move
所做的只是将其参数转换为右值,但临时 Foo(1)
已经是右值,因此您将右值转换为右值:无用。此外,如果没有 std::move
,编译器可以执行 copy elision 并优化实际移动,但是当您使用 std::move
时,它不能这样做,您将代码设为 更慢而不是更快!
最佳代码是最简单的版本:
std::tuple<Foo> tup(Foo(1));
或者更简单:
std::tuple<Foo> tup(1);
这段代码
#include <tuple>
struct Foo
{
Foo(const int& value):value_(value){}
//Foo(const Foo&)=delete; // delete copy constructor
int value_;
};
int main()
{
std::tuple<Foo> tup(std::move(Foo(1)));
return 0;
}
工作正常,但如果删除 Foo
复制构造函数,它将失败并出现以下编译错误:使用已删除的函数 Foo::Foo(const Foo&)
.
但是,既然我明确告诉对象可以移动,为什么 std::tuple
构造函数使用 Foo
复制构造函数而不是它的移动构造函数?如何强制构建 std::tuple
移动 Foo
实例而不是复制它?
But, since I am telling explicitly that the object can be moved,
不,您是在告诉编译器您想要移动对象。这不是一回事。
why the
std::tuple
constructor uses theFoo
copy constructor instead of its moving constructor?
因为删除复制构造函数时隐含的移动构造函数不存在,所以不能使用
How can I enforce the std::tuple to be constructed moving the Foo instance instead of copying it?
要么不删除复制构造函数,要么也定义一个移动构造函数:
struct Foo
{
Foo(const int& value):value_(value){}
Foo(const Foo&)=delete; // delete copy constructor
Foo(Foo&&)=default;
int value_;
};
N.B。这里的std::move
完全没用:
std::tuple<Foo> tup(std::move(Foo(1)));
std::move
所做的只是将其参数转换为右值,但临时 Foo(1)
已经是右值,因此您将右值转换为右值:无用。此外,如果没有 std::move
,编译器可以执行 copy elision 并优化实际移动,但是当您使用 std::move
时,它不能这样做,您将代码设为 更慢而不是更快!
最佳代码是最简单的版本:
std::tuple<Foo> tup(Foo(1));
或者更简单:
std::tuple<Foo> tup(1);