我正在学习提升的变体,并发现它在此代码段中从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*
?
答案 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
。