重载的Bool / String歧义

时间:2014-10-16 21:11:04

标签: 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;
}

输出:1

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

4 个答案:

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

它会给出预期的结果。

为什么会这样?

这是因为标准转换:

  • “hello”被理解为const char*指针
  • 此指针可以转换为bool(标准的4.12部分:“(...)prvalue(...)指针(...)类型可以转换为bool类型的prvalue 。“
  • 不考虑从“hello”到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)

选择重载方法时,这是编译器尝试的顺序:

  1. 完全匹配
  2. 促销
  3. 标准数字转换
  4. 用户定义的运算符
  5. 指针不会升级到bool,但会转换为boolchar*使用std运算符转换为std::string。请注意,如果char*使用此列表中的相同数字转换为 boolstd::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::stringconst char*提供重载,也不会在客户呼叫站点上构建std::string代码。

我并不认为这样会更好,但它更简单。