重载的Bool/String歧义

Gil*_*pie 10 c++ string casting boolean overloading

为什么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;
}
Run Code Online (Sandbox Code Playgroud)

输出: 1

是因为编译器不够聪明,无法从char*跳转到字符串,而只是假设bool是最接近指针的东西?我唯一的选择是创建一个显式的char*构造函数,它基本上与字符串构造函数完全相同吗?

0x4*_*2D2 16

如果你有C++ 11,你可以使用委托构造函数:

A(char const* s) : A(std::string(s)) { }
Run Code Online (Sandbox Code Playgroud)

被选择在一个用于布尔转换构造函数的原因std::string是因为从转换char const*bool是一个标准转换,而所述一个到std::string是一个用户定义的转换.标准转化的排名高于用户定义的转化次数.


Chr*_*phe 5

A(string("hello"));
Run Code Online (Sandbox Code Playgroud)

它会给出预期的结果。

为什么会这样呢?

这是因为标准转换:

  • “你好”被理解为const char*指针
  • this 指针可以转换为 a bool(标准第 4.12 节:“(...) 指针 (...) 类型的纯右值可以转换为 bool 类型的纯右值。”
  • string不考虑从“hello”到“hello”的转换,因为标准第12.3节解释了“类对象的类型转换可以由构造函数和转换函数指定。这些转换称为用户定义的转换”和“应用用户定义的转换”只有在他们明确的地方”。如果您没有bool构造函数,std::string转换将隐式完成。

如何得到你所期望的?

只需添加字符串文字缺少的构造函数:

A(const char* v)
{
    cout << v;  // or convert v to string if you want to store it in a string member
}
Run Code Online (Sandbox Code Playgroud)

当然,您可以选择另一个答案中 0x499602D2 建议的委托,而不是从头开始重写构造函数。