为什么从char *到std :: string的转换比片段中的const char *更优先?

时间:2015-02-25 10:41:47

标签: c++ string boost type-conversion

我正在学习提升的变体,并发现它在此代码段中从char*隐式转换为std::string

boost::variant<int, char*, std::string> v;
// implicitly converted from char* to std::string, so we can't store char* and std::string both?
v = "123";
std::cout << "boost::variant value: " << boost::get<std::string>(v) << std::endl;
v = 1;
std::cout << "boost::variant value: " << boost::get<int>(v) << std::endl;
v = "123";
std::cout << "boost::variant value: " << boost::get<char*>(v) << std::endl;

因此boost::get<char*>(v)调用会引发异常。我有点想知道并尝试使其更公平:在类型名称列表中将char*更改为const char*

boost::variant<int, const char*, std::string> v;
v = "123";
std::cout << "boost::variant value: " << boost::get<std::string>(v) << std::endl;

现在异常是正确的。但我的问题是:为什么编译器/库选择std::string而不是我指定的char*?我理解,v = "123"const char*的分配,但为什么会转换为std::string而不是char*

2 个答案:

答案 0 :(得分:3)

const char *并非隐式转换为char *,因为这样会不安全。 const的重点是您不会无意中尝试修改对象。假设const char *隐式转换为char *。然后是什么阻止这些程序:

#include <cstdio>
void f(char *s) { *s = 'a'; }
int main() { const char *str = "Hello!"; f(str); std::puts(str); }

这显然是一个巨大的错误,编译时甚至没有警告?

答案 1 :(得分:1)

因为从const char *明确地从std::string转换为std::string,并且由于显而易见的原因,永远不会隐式删除const