为什么不能创建一个包含一个元组和一个 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 包含另一个 tupleunique_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)