此代码适用于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看起来很相关,但它谈到了一个固定的错误并且已经很老了。
答案 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
)。