赋值运算符的布尔和字符串重载(C ++)

时间:2013-02-22 19:44:57

标签: c++ string boolean operator-overloading assignment-operator

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

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

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

2 个答案:

答案 0 :(得分:9)

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 类型为“N T数组”或“T未知数组的数组”的左值或右值可以转换为“指向T的指针”类型的prvalue。结果是指向数组的第一个元素的指针。

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

  

4.12布尔转换[conv.bool]

     

1 算术,无范围枚举,指针或指向成员类型的指针的prvalue可以转换为bool类型的prvalue。零值,空指针值或空成员指针值将转换为false;任何其他值都将转换为true。类型std::nullptr_t的prvalue可以转换为bool类型的prvalue;结果值为false

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

要解决您的问题,我建议您添加另一个需要const char*的重载版本,并将其转发到const std::string&重载。

答案 1 :(得分:3)

丹尼尔是对的。

简短的回答是std::string不是内置类型,因此不会获得任何神奇的优惠待遇。不幸的是,"hi world"之类的字符串文字的类型是而不是 std::string,而是更容易转换为内置类型{{1的指针类型而不是“用户定义的”类型bool

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

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