为啥在片段中从 char* 转换为 std::string 比转换为 const char* 更可取?

Posted

技术标签:

【中文标题】为啥在片段中从 char* 转换为 std::string 比转换为 const char* 更可取?【英文标题】:Why conversion from char* to std::string is more preferred than to const char* in the snippet?为什么在片段中从 char* 转换为 std::string 比转换为 const char* 更可取? 【发布时间】:2015-02-25 10:41:47 【问题描述】:

我在学习 boost 的 variant,发现它在这个 sn-p 中实现了从 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&lt;char*&gt;(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*

【问题讨论】:

为什么人们坚持在与C无关的问题中添加c标签? 好吧,对不起,我首先指向“c++”,但它添加了“c”。接下来我忘记删除了。 如果这是一个可重现的问题(如果您可以描述添加 c++ 标签的确切步骤,以及系统添加 c 标签的位置),我鼓励您将其报告为一个错误。这从来没有发生在我身上,我什至无法让 c 和 c++ 同时出现在标签选择中,但我不排除你做一些我没想过的事情的可能性. 感谢您的建议。我不记得我到底做了什么,但我记得我指的是“c++”,但也许我当时也做了其他事情(点击、按键等)。好吧,如果我要重现它我会按照你对我的建议去做。我也不是要在这里放“c”标签,但现在我想——为什么不呢?问题是关于char*const char*之间的c型转换,不是吗? 不,C 和 C++ 是不同的语言,即使对于两种语言都存在的类型,这些类型之间的转换在 C++ 中与在 C 中不同。如果 C 确实有隐式转换从 const char *char *(幸运的是,它没有),这对 C++ 没有影响。如果 C 使 "123" 成为 char[4] 而不是 const char[4](不幸的是),这对 C++ 也没有影响,并且与您的问题无关。 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于为啥在片段中从 char* 转换为 std::string 比转换为 const char* 更可取?的主要内容,如果未能解决你的问题,请参考以下文章

为啥编译器试图将 char * 转换为 char? [关闭]

在 oracle 中从日期格式转换为日期格式

为啥从字符串常量转换为 'char*' 在 C 中有效但在 C++ 中无效

为啥仅在某些情况下才能将字符串文字隐式转换为 char* ? [复制]

为啥将“0”添加到 int 数字允许转换为 char?

Java - 为啥 char 不应该被隐式转换为字节(和短)原语?