为什么C ++会将字符串文字转换为bool而不是字符串?
#include <iostream>
using namespace std;
class A
{
public:
A(string v)
{
cout << v;
}
A(bool v)
{
cout << v;
}
};
int main()
{
A("hello");
return 0;
}
输出:1
是因为编译器不够聪明,无法从char *跳转到字符串,而只是假设bool是最接近指针的东西吗?我唯一的选择是创建一个显式的char *构造函数,它基本上与字符串构造函数完全相同吗?
答案 0 :(得分:16)
如果你有C ++ 11,你可以使用委托构造函数:
A(char const* s) : A(std::string(s)) { }
选择布尔转换构造函数而不是std::string
的原因是因为从char const*
到bool
的转换是标准转换,而std::string
转换为{{1}}是用户定义的转换。标准转化的排名高于用户定义的转化次数。
答案 1 :(得分:4)
使用
A(string("hello"));
它会给出预期的结果。
为什么会这样?
这是因为标准转换:
const char*
指针bool
(标准的4.12部分:“(...)prvalue(...)指针(...)类型可以转换为bool类型的prvalue 。“)string
的转换,因为标准的第12.3节解释了“类对象的类型转换可以由构造函数和转换函数指定。这些转换称为用户 - 定义的转换“和”用户定义的转换仅在明确无误的情况下应用“。您是否拥有bool
构造函数,std::string
转换将被隐含地完成。 如何达到预期目标?
只需添加缺少的字符串litterals构造函数:
A(const char* v)
{
cout << v; // or convert v to string if you want to store it in a string member
}
当然,不是从头开始重写构造函数,而是可以在另一个答案中选择0x499602D2建议的委托。
答案 2 :(得分:2)
选择重载方法时,这是编译器尝试的顺序:
指针不会升级到bool
,但会转换为bool
。 char*
使用std
运算符转换为std::string
。请注意,如果char*
使用此列表中的相同数字转换为 bool
和std::string
,则编译器应选择哪种方法是不明确的,因此编译器会抛出一个&#34;模糊的重载&#34;错误。
我会把重点放在0x499602D2的解决方案之上。如果您有C ++ 11,最好打电话:A(char* s) : A(std::string(s)){}
如果您没有C ++ 11,那么我将创建一个A(char* s)
构造函数并将A(std::string)
构造函数的逻辑抽象为一个方法,并从两个构造函数中调用该方法。
http://www.learncpp.com/cpp-tutorial/76-function-overloading/
答案 3 :(得分:2)
最近我也传递了这个问题,让我分享另一种方式。
您可以将bool
构造函数更改为unsigned char
。因此,字符串文字的衰变和隐含转换不会发生,std::string
构造函数会发生。
class A
{
public:
A(string v)
{
cout << v;
}
A(unsigned char v)
{
cout << static_cast<bool>(v);
}
};
int main()
{
A("Hello"); // <- Call A(string)
A(false); // <- Call A(unsigned char)
}
通过这种方式,您不需要始终为std::string
和const char*
提供重载,也不会在客户呼叫站点上构建std::string
代码。
我并不认为这样会更好,但它更简单。