为什么字符串支持`operator =(char)`?

Com*_*hip 18 c++ c++11

今天我的一位同事在我们的代码中发现了一个非常微妙的错误,基本上是这样的:

double d = 65;
std::string s = "Hello world";

// .. somewhere later, accidentally assigning to s instead of a similarly
// named numerical variable.
s = d;

// s is now 'A' 
Run Code Online (Sandbox Code Playgroud)

我发现,发生这个错误的原因是它std::basic_string<_Elem>有一个赋值运算符

_Myt& operator=(_Elem _Ch)
{ // assign 1 * _Ch
  return (assign(1, _Ch));
}
Run Code Online (Sandbox Code Playgroud)

现在编译器并没有真正抱怨(很多,如果级别足够高,它会发出关于缩小转换的警告).我们似乎很早就抓住了这个漏洞,它没有造成很大的破坏,但我想知道为什么这是允许的.毕竟,我不能写

std::string s = 65;
Run Code Online (Sandbox Code Playgroud)

因为std::string没有(n隐式)构造函数需要一个char.将它作为一种迫使你写作的明确转换会不会更安全

std::string s = string('A');
Run Code Online (Sandbox Code Playgroud)

这将禁止分配给单个_Elem(char).

这个赋值运算符是否有任何原因?正如同一位同事正确注意到的那样,

double d;
char c = d;
Run Code Online (Sandbox Code Playgroud)

是允许的

int* p = d;
Run Code Online (Sandbox Code Playgroud)

不是(对于任何指针大小) - 可能是因为从数字到指针的隐式转换被认为是危险的.事实上,它甚至似乎已经变成了C++ 11,据我所知,它在数据类型管理方面试图非常严格和有用.

Yak*_*ont 15

30年前写过图书馆的人std::string认为这是一个好主意.

在标准化之前,它没有被删除.

从那时起,删除它将有可能破坏遗留代码,这是一种成本.

deprecated属性最近才被添加到C++中,它允许一种标准方式告诉用户一个函数它很快就会消失.没有人设法让它被弃用,这是一个明智的步骤需要它被删除(只是删除它将是粗鲁的).我鼓励你提出这样的建议.

  • 两件事情.首先,`std :: string`未从现有库导入.它专为C++标准库而设计.其次,弃用并不意味着某些东西会消失(不久或其他).这只意味着**可能会消失.例如,C标准头文件是C++的一部分,但已弃用.它们永远不会消失.(当然,它们不应该被弃用,但这是另一回事) (5认同)
  • 我建议将[[deprecated]]属性添加到该成员函数并通过C++ 17删除它.毕竟,它可以通过赋值给braced-init-list轻松替换,例如`s = {'5'};` (2认同)
  • @Columbo通过C++删除它17似乎过于激进:在删除它之前,应该至少弃用一个标准版本.我会为C++ 17争论`[[deprecated]]`,然后建议在C++ 2x或C++ 2y中删除它. (2认同)
  • 哎呦!我的错.我想说"按照C++ 17之后的标准".显然,我们只能在C++ 17中引入该属性.:) (2认同)