为什么在代码段中从 char* 转换为 std::string 比转换为 const char* 更受欢迎?

Why conversion from char* to std::string is more preferred than to const char* in the snippet?

我在学习 boost 的 变体 并发现它在这段代码中进行了从 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;

现在例外是正确的。但我的问题是:为什么 compiler/library 选择 std::string 而不是我指定的 char*?我明白,v = "123"const char* 的赋值,但为什么它转换为 std::string 而不是 char*

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); }

这显然是一个巨大的错误,在没有警告的情况下进行编译?

因为从 std::string 有一个从 const char *std::string 的显式转换,并且由于显而易见的原因,从未隐式地删除 const