为什么在元组初始化中复制构造的对象?
Why are constructed objects, in tuple initialization, copied?
我有一种情况无法解决。我定义了一个不可复制的结构,并想在一个元组中就地构造它。如果我这样做,它就会被复制。我认为问题可能出在 std::make_tuple
,但事实并非如此。
如果我改为构建对象,然后将其移动到元组中,事情就会按预期进行。
演示(我用的是std::exit
防止输出正常破坏)
#include <tuple>
#include <iostream>
#include <cstdlib>
struct MoveMe {
MoveMe(size_t s) : size(s) {}
MoveMe(MoveMe&&) = default;
MoveMe(const MoveMe&) = delete;
MoveMe& operator=(MoveMe&&) = default;
MoveMe& operator=(const MoveMe&) = delete;
~MoveMe() {
std::cout << "Destroyed" << std::endl;
}
size_t size = 0;
};
int main(int, char**) {
std::cout << "Constructed in-place." << std::endl;
auto tuple = std::make_tuple(MoveMe{10});
std::cout << std::endl << "Other tests." << std::endl;
std::tuple<MoveMe> tuple2 = std::tuple<MoveMe>(MoveMe{10});
std::cout << std::endl << "Moved." << std::endl;
MoveMe obj{10};
auto tuple3 = std::make_tuple(std::move(obj));
std::exit(0);
// return 0;
}
产出
Constructed in-place.
Destroyed
Other tests.
Destroyed
Moved.
知道这是为什么吗?我对右值的理解是基本的,所以我猜我遗漏了一些明显的东西。谢谢。
它不是复制的,它仍然是移动的。
在您的情况下,您正在创建一个临时 (MoveMe{10}
),然后用于移动构造元组中 MoveMe
的实例。元组中MoveMe
的实例被移动构造后,被移动的临时对象被销毁。
可以通过转发参数直接构造元组中的MoveMe
对象
std::cout << "Directly Constructed" << std::endl;
auto tuple = std::tuple<MoveMe>(10);
这不会导致临时创建然后销毁。
我有一种情况无法解决。我定义了一个不可复制的结构,并想在一个元组中就地构造它。如果我这样做,它就会被复制。我认为问题可能出在 std::make_tuple
,但事实并非如此。
如果我改为构建对象,然后将其移动到元组中,事情就会按预期进行。
演示(我用的是std::exit
防止输出正常破坏)
#include <tuple>
#include <iostream>
#include <cstdlib>
struct MoveMe {
MoveMe(size_t s) : size(s) {}
MoveMe(MoveMe&&) = default;
MoveMe(const MoveMe&) = delete;
MoveMe& operator=(MoveMe&&) = default;
MoveMe& operator=(const MoveMe&) = delete;
~MoveMe() {
std::cout << "Destroyed" << std::endl;
}
size_t size = 0;
};
int main(int, char**) {
std::cout << "Constructed in-place." << std::endl;
auto tuple = std::make_tuple(MoveMe{10});
std::cout << std::endl << "Other tests." << std::endl;
std::tuple<MoveMe> tuple2 = std::tuple<MoveMe>(MoveMe{10});
std::cout << std::endl << "Moved." << std::endl;
MoveMe obj{10};
auto tuple3 = std::make_tuple(std::move(obj));
std::exit(0);
// return 0;
}
产出
Constructed in-place.
Destroyed
Other tests.
Destroyed
Moved.
知道这是为什么吗?我对右值的理解是基本的,所以我猜我遗漏了一些明显的东西。谢谢。
它不是复制的,它仍然是移动的。
在您的情况下,您正在创建一个临时 (MoveMe{10}
),然后用于移动构造元组中 MoveMe
的实例。元组中MoveMe
的实例被移动构造后,被移动的临时对象被销毁。
可以通过转发参数直接构造元组中的MoveMe
对象
std::cout << "Directly Constructed" << std::endl;
auto tuple = std::tuple<MoveMe>(10);
这不会导致临时创建然后销毁。