使用std :: unique_ptr创建std :: pair或std :: map作为值隐含

时间:2016-06-24 23:10:37

标签: c++11 stdmap std-pair

此代码适用于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的{​​{1}}。

This answer看起来很相关,但它谈到了一个固定的错误并且已经很老了。

1 个答案:

答案 0 :(得分:4)

将单个原始指针作为输入的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)。