为什么在代码段中从 char* 转换为 st::string 比从 const char* 更可取

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

本文关键字:char 比从 string const 代码 段中 为什么 转换 st      更新时间:2023-10-16

我正在学习 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;

现在异常是正确的。但我的问题是:为什么编译器/库选择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永远不会隐式完成。