为什么不能创建一个包含一个元组和一个 unique_ptr 作为 C++ 值的元组?
Why isn't it possible to make a tuple which contains a tuple and a unique_ptr as values in C++?
将 std::unique_ptr
放在 std::tuple
中没有任何问题,但是当 tuple
包含另一个 tuple
和 unique_ptr
作为元素时,然后编译器抛出一个错误。
示例:
std::tuple<int, std::unique_ptr<Entity>> tupleA {1, std::move(new Entity)};
//this line throws an error!
std::tuple<std::tuple<int, int>, std::unique_ptr<Entity>> tupleB {{1, 1}, std::move(new Entity)};
第二行,创建 `tupleB` 抛出以下错误:
error: no matching constructor for initialization of ´std::tuple<std::tuple<int, int>,std::unique_ptr<Entity>>´
note: candidate constructor template not viable: cannot convert initializer list argument to ´std::allocator_arg_t´
这里的问题到底是什么?
std::forward_as_tuple(1, 1)
而不是 {1, 1}
应该可以。
TL;DR
更改您的代码,使其显示为
std::tuple<std::tuple<int, int>, std::unique_ptr<Derived>> tupleB{std::make_tuple(1,1), std::move(new Derived)};
详情
您的编译器会告诉您哪里出了问题。它说(在这种情况下为 MSVC)
error C2440: 'initializing': cannot convert from 'initializer list' to 'std::tuplestd::tuple<int,int,std::unique_ptr<Derived,std::default_delete>>'
所以不要像这样使用初始化列表
std::tuple<std::tuple<int, int>, std::unique_ptr<Derived>> tupleB{std::make_tuple(1,1), std::move(new Derived)};
问题如下:
当容器用大括号内的值初始化时,如 { 1, 1},这被推断为类型 std::initializer_lists<const char *>
。反过来,编译器会寻找一个容器构造函数,该构造函数将初始化列表作为参数。
你不能使用初始化列表来初始化元组,你必须像下面这样使用 std::make_tuple
:
std::tuple<std::tuple<int, int>, std::unique_ptr<Entity>> tupleB {std::make_tuple<int, int>(1, 1), std::move(new Entity)};
而不是 {1, 1}
使用 std::make_tuple(1, 1)
将 std::unique_ptr
放在 std::tuple
中没有任何问题,但是当 tuple
包含另一个 tuple
和 unique_ptr
作为元素时,然后编译器抛出一个错误。
示例:
std::tuple<int, std::unique_ptr<Entity>> tupleA {1, std::move(new Entity)};
//this line throws an error!
std::tuple<std::tuple<int, int>, std::unique_ptr<Entity>> tupleB {{1, 1}, std::move(new Entity)};
第二行,创建 `tupleB` 抛出以下错误:
error: no matching constructor for initialization of ´std::tuple<std::tuple<int, int>,std::unique_ptr<Entity>>´
note: candidate constructor template not viable: cannot convert initializer list argument to ´std::allocator_arg_t´
这里的问题到底是什么?
std::forward_as_tuple(1, 1)
而不是 {1, 1}
应该可以。
TL;DR
更改您的代码,使其显示为
std::tuple<std::tuple<int, int>, std::unique_ptr<Derived>> tupleB{std::make_tuple(1,1), std::move(new Derived)};
详情
您的编译器会告诉您哪里出了问题。它说(在这种情况下为 MSVC)
error C2440: 'initializing': cannot convert from 'initializer list' to 'std::tuplestd::tuple<int,int,std::unique_ptr<Derived,std::default_delete>>'
所以不要像这样使用初始化列表
std::tuple<std::tuple<int, int>, std::unique_ptr<Derived>> tupleB{std::make_tuple(1,1), std::move(new Derived)};
问题如下:
当容器用大括号内的值初始化时,如 { 1, 1},这被推断为类型 std::initializer_lists<const char *>
。反过来,编译器会寻找一个容器构造函数,该构造函数将初始化列表作为参数。
你不能使用初始化列表来初始化元组,你必须像下面这样使用 std::make_tuple
:
std::tuple<std::tuple<int, int>, std::unique_ptr<Entity>> tupleB {std::make_tuple<int, int>(1, 1), std::move(new Entity)};
而不是 {1, 1}
使用 std::make_tuple(1, 1)