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

发布于 2024-09-30 06:33:44 字数 116 浏览 4 评论 0原文

这更多的是一个政策或一个历史问题。为什么决定不为 std::string 提供 const char * 转换?是否担心有人可能会执行 printf("%s", s) 并相信它会自动转换?是否有关于这个问题的公开讨论?

This is more of a policy or a historical question. Why was it decided not to provide a const char * conversion for std::string? Were there a fear someone might do printf("%s", s) and believe it would automatically convert? Are there any open discussions on this issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

养猫人 2024-10-07 06:33:44

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

Automatic casts are almost always evil. If there were a cast to const char *, a std::string could be also automatically cast to other pointer types and that could lead to hard to find bugs. There is the c_str() method that returns const char * so you can still achieve what you need. Also, the typecast is not logically correct - std::string is not equivalent to const char *.

伤痕我心 2024-10-07 06:33:44

string 类内部不需要存储以 0 结尾的字符串。事实上,如果它不想的话,它甚至不必将它们存储在连续的内存中。因此,隐式转换没有意义,因为它可能是一项代价高昂的操作。

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

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

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

The string class internally need not store the string with a terminating 0. In fact it doesn't even have to store them in contiguous memory if it didn't want to. Therefore an implicit cast doesn't make sense, since it may be a costly operation.

The c_str() function then gives you the c-string. Depending on how the library stores it internally this function may have to create a temporary. This temporary is only valid until you modify the string.

It is unfortunately however since a string could just been specified to be a c-string internally. This wouldn't lead to any loss of functionality and would allow an implicit conversion.

Edit The standard does basically imply the memory is contiguous (if accessed through data() or the [] operator), though it need not be internally, and certainly not null terminated. Likely all implementations store the 0 as well. If this were standardized then the implicit conversion could be safely defined.

无需解释 2024-10-07 06:33:44

关于您之前的评论:

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

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

C++0x 引入了显式转换运算符的概念,但在此之前它们是隐式的,这意味着(在查看代码时)它们是否会被使用永远不清楚。

隐式转换是不好的,特别是因为它们可以级​​联,从而导致代码极其晦涩。

此外,正如已经指出的,这里存在一个正确性问题。因为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...
}

Regarding your previous comments:

If they are equivalent then there is no difference (except for convenience) to use cast instead of the c_str() call

There is one very important difference: one is implicit whereas the other is explicit.

C++0x introduces the notion of explicit cast operators, but until then they are implicit, meaning that it is never clear (when looking at the code) whether they will be used or not.

Implicit cast are bad, especially since they can be cascaded, leading to extremely obscure code.

Moreover, as already stated, there is here a problem of correctness. Because the pointer returned by c_str is only valid as long as the string object does not change, then you could find yourself with hard to find bugs. Consider:

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...
}
予囚 2024-10-07 06:33:44

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

它通常会在您不希望发生的转换发生时让您感到困扰,并且会使您的代码难以调试。

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

My feeling is that C++ is a strongly typed language and implicit type conversions break type-safety.

It can often bite you where the conversion happens at a point where you do not expect it and can make your code hard to debug.

Non-explicit constructors can have a similar effect and std::string itself does have an implicit constructor from const char *. In this case it is not necessarily a bad thing although it can lead to inefficient code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文