6

我正在定义赋值运算符的多个重载,如下所示:

Foo.h

class Foo
{
private:
    bool my_bool;
    int my_int;
    std::string my_string;
public:
    Foo& operator= (bool value);
    Foo& operator= (int value);
    Foo& operator= (const std::string& value);
};

Foo.cpp

// Assignment Operators.
Foo& Foo::operator= (bool value) {my_bool = value; return *this;}
Foo& Foo::operator= (int value) {my_int = value; return *this;}
Foo& Foo::operator= (const std::string& value) {my_string = value; return *this;}

这是我的 main.cpp(请参阅标记为 的评论SURPRISE):

Foo boolFoo;
Foo intFoo;
Foo stringFoo;

// Reassign values via appropriate assignment operator.
boolFoo = true;                // works...assigned as bool
intFoo = 42;                   // works...assigned as int
stringFoo = "i_am_a_string";   // SURPRISE...assigned as bool, not string

std::string s = "i_am_a_string";
stringFoo = s;                 // works...assigned as string

// works...but awkward
stringFoo = static_cast<std::string>("i_am_a_string");

问题:有人能告诉我为什么在布尔上下文中评估未转换的字符串文字吗?

4

2 回答 2

11

C++ 标准在第 13.3 章中定义了重载解析规则,您可以在其中找到:

13.3.3.2 对隐式转换序列进行排名[over.ics.rank]

2在比较隐式转换序列的基本形式时(定义见 13.3.3.1)

— 标准转换序列 (13.3.3.1.1) 是比用户定义的转换序列或省略号转换序列更好的转换序列,并且

— 用户定义的转换序列 (13.3.3.1.2) 是比省略号转换序列 (13.3.3.1.3) 更好的转换序列。

这意味着编译器将更喜欢从字符串文字到boolint如果可用的标准转换序列。现在,哪些标准转换是相关的?在您的情况下,这两个是相关的:

4.2 数组到指针的转换[conv.array]

1 “NT 数组”或“T 的未知边界数组”类型的左值或右值可以转换为“指向 T 的指针”类型的纯右值。结果是指向数组第一个元素的指针。

此转换将类型为 的字符串文字转换const char[N]const char*. 第二个是:

4.12 布尔转换 [conv.bool]

1算术、无作用域枚举、指针或指向成员类型的指针的纯右值可以转换为类型的纯右值bool。零值、空指针值或空成员指针值转换为false; 任何其他值都转换为true. 类型的纯右值std::nullptr_t可以转换为类型的纯右值bool;结果值为false

这就是指针转换为bool. 由于存在标准转换序列,因此std::string不使用用户定义的转换为。

为了解决您的问题,我建议您添加另一个重载版本,将const char*调用转发给const std::string&重载。

于 2013-02-22T19:48:55.307 回答
4

丹尼尔是对的。

简短的回答是它std::string不是内置类型,因此没有任何神奇的优惠待遇。不幸的是,字符串文字的类型"hi world"不是,而是 一种指针类型,它比“用户定义” std::string类型更容易转换为内置类型。boolstd::string

基本上,答案是:欢迎使用 C++。

是的,我知道,它来自标准库,不,没关系。

于 2013-02-22T20:22:07.063 回答