赋值运算符的布尔和字符串重载 (C++)
我正在定义赋值运算符的多个重载,如下所示:
I am defining multiple overloads of the assignment operator as follows:
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
的评论):
And here's my main.cpp (see the comment marked 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");
问题:有人能告诉我为什么要在布尔上下文中评估未转换的字符串文字吗?
Question: Can someone tell me why an uncasted string literal is being evaluated in a boolean context?
推荐答案
C++ 标准在第 13.3 章中定义了重载解析规则,你可以找到:
The C++ standard defines overload resolution rules in chapter 13.3, there you find:
13.3.3.2 对隐式转换序列进行排名[over.ics.rank]
2比较隐式转换序列的基本形式时(定义见13.3.3.1)
2 When comparing the basic forms of implicit conversion sequences (as defined in 13.3.3.1)
――标准转换序列 (13.3.3.1.1) 是比用户定义的转换序列或省略号转换序列更好的转换序列,并且
― a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence, and
- 用户定义的转换序列 (13.3.3.1.2) 是比省略号转换序列 (13.3.3.1.3) 更好的转换序列.
― a user-defined conversion sequence (13.3.3.1.2) is a better conversion sequence than an ellipsis conversion sequence (13.3.3.1.3).
这意味着编译器将首选从字符串文字到 bool
或 int
的标准转换序列(如果可用).现在,哪些标准转换是相关的?在您的情况下,这两个是相关的:
This means that the compiler will prefer a standard conversion sequence from the string literal to bool
or int
if available. Now, which standard conversions are relevant? In your case, these two are relevant:
4.2 数组到指针的转换[conv.array]
1 N T 的数组"或T 的未知边界数组"类型的左值或右值可以转换为指向 T 的指针"类型的纯右值.结果是指向数组第一个元素的指针.
1 An lvalue or rvalue of type "array of N T" or "array of unknown bound of T" can be converted to a prvalue of type "pointer to T". The result is a pointer to the first element of the array.
此转换将类型为 const char[N]
的字符串文字转换为 const char*
.第二个是:
This conversion turns the string literal, which is of type const char[N]
, into a const char*
. The second one is:
4.12 布尔转换 [conv.bool]
1 算术纯右值、无作用域枚举、指针或指向成员类型的指针可以转换为 bool
类型的纯右值.零值、空指针值或空成员指针值转换为false
;任何其他值都将转换为 true
.std::nullptr_t
类型的纯右值可以转换为 bool
类型的纯右值;结果值为 false
.
1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool
. A zero value, null pointer value, or null member pointer value is converted to false
; any other value is converted to true
. A prvalue of type std::nullptr_t
can be converted to a prvalue of type bool
; the resulting value is false
.
这就是指针转换为bool
的原因.由于存在标准转换序列,因此不使用用户定义的到 std::string
的转换.
That is the reason why the pointer is converted to bool
. Since a standard conversion sequence exists, the user-defined conversion to std::string
is not used.
为了解决您的问题,我建议您添加另一个采用 const char*
的重载版本,并将调用转发到 const std::string&
重载.
To solve your problem, I suggest you add another overloaded version that takes const char*
and make it forward the call to the const std::string&
overload.
相关文章