以 std::unique_ptr 作为值隐式创建 std::pair 或 std::map

Create std::pair or std::map with std::unique_ptr as value implicitely

此代码适用于 Visual Studio:

typedef struct {
    int a;
} data_t;

using datap_t = std::unique_ptr<data_t>;
using MyPair = std::pair<std::string, datap_t>;

int main() {
    data_t * pd1 = new data_t();
    MyPair p("tst", pd1); // This does not compile in gcc or clang
    // MyPair p2("tst", datap_t(pd1)); // This compiles

    return 0;
}

但是 clang 和 gcc 报错:

error: no matching function for call to 'std::pair<const std::basic_string<char>, std::unique_ptr<data_t> >::pair(const char [3], data_t*&)

Here 是值得一试的想法。

我可以调用 datap_t(pd1) 并且它编译的事实意味着构造函数是有效的,那么为什么该模板找不到合适的匹配项?

我一直在寻找使用 emplace 将键值对添加到地图,这就是为什么我首先想要进行这种隐式转换的原因。请注意,与 Visual Studio 一样,隐式转换适用于大多数其他类型,例如 std::string 来自 "raw string".

This answer 看起来很相关,但它谈论的是一个已修复的错误并且很旧。

将单个原始指针作为输入的 std::unique_ptr 构造函数标记为 explicit 以防止隐式转换。

pd1 是原始指针。 MyPair p("tst", pd1); 涉及到 std::unique_ptr 的隐式转换,这就是编译在 Clang 和 GCC 中失败的原因,这是应该的。您必须改用显式转换:

MyPair p("tst", datap_t(pd1));

更好的选择是完全不使用原始指针:

MyPair p("tst", std::make_unique<data_t>());

Clang 和 GCC 正在做正确的事情,Visual Studio 不是(尽管它的 unique_ptr documentation 显示相关构造函数是 explicit)。