为什么std :: string没有提供到const char *的转换?

时间:2010-11-04 11:33:42

标签: c++ string implicit-conversion

这更像是一个政策或历史问题。为什么为std :: string提供const char *转换?有人害怕有人可能会做printf(“%s”,s)并相信它会自动转换吗?是否有关于这个问题的公开讨论?

4 个答案:

答案 0 :(得分:28)

自动演员几乎总是邪恶的。如果有const char *转换,std::string也可以自动转换为其他指针类型,这可能导致很难找到错误。有c_str()方法返回const char *,因此您仍然可以实现所需。此外,类型转换在逻辑上不正确 - std::string不等同于const char *

答案 1 :(得分:11)

字符串类在内部不需要存储终止为0的字符串。事实上,如果它不想要它甚至不必将它们存储在连续的内存中。因此,隐式演员表没有意义,因为这可能是一项代价高昂的操作。

c_str()函数然后为您提供c-string。根据库在内部存储它的方式,此函数可能必须创建一个临时的。此临时值仅在您修改字符串之前有效。

不幸的是,因为字符串可以在内部被指定为c字符串。这不会导致任何功能损失,并允许隐式转换。

编辑标准基本上暗示内存是连续的(如果通过data()或[]运算符访问),虽然它不需要在内部,当然也不会以空值终止。可能所有实现都存储0。如果这是标准化的,则可以安全地定义隐式转换。

答案 2 :(得分:5)

关于您之前的评论:

  

如果它们是等价的,那么使用强制转换而不是c_str()调用没有区别(除了方便)

有一个非常重要的区别:一个是隐含的,另一个是显性的。

C ++ 0x引入了explicit强制转换操作符的概念,但在此之前它们是隐式的,这意味着它(从查看代码时)是否永远不会被清除(

隐式演员阵容很糟糕,特别是因为它们可以级​​联,导致代码非常模糊。

此外,如上所述,这里存在正确性问题。因为只有c_str对象没有改变,string返回的指针才有效,那么你可能会发现很难找到错误。考虑:

void function()
{
  std::map<int, char const*> map;

  map[1] = boost::lexical_cast<std::string>(47);

  std::cout << map[1] << std::endl; // CRASH here, if lucky...
}

答案 3 :(得分:1)

我的感觉是C ++是一种强类型语言,隐式类型转换打破了类型安全。

它往往会让你感觉到转换发生在你不期望的地方,并且可能使你的代码难以调试。

非显式构造函数可以具有类似的效果,并且std :: string本身具有来自const char *的隐式构造函数。在这种情况下,它不一定是坏事,尽管它可能导致代码效率低下。