字符串字面匹配布尔过载,而不是的std :: string(String literal match

2019-07-19 14:53发布

我试图写有一些重载方法C ++类:

class Output
{
public:
    static void Print(bool value)
    {
        std::cout << value ? "True" : "False";
    }

    static void Print(std::string value)
    {
        std::cout << value;
    }
};

现在可以说,我调用该方法如下:

Output::Print("Hello World");

这是结果

真正

那么,为什么,当我已经定义的方法可以接受布尔和字符串,它使用布尔超负荷当我通过在非布尔值?

编辑:我来自一个C#/ Java环境,所以很新的C ++!

Answer 1:

"Hello World"是字符串文字类型“12的阵列的const char ,其可以被转换为一个”指针“ const char ”,这又可以转换成bool 。 这正是发生了什么。 编译器更喜欢这种使用std::string的转换构造函数。

涉及转换构造A转换序列被称为用户定义的转换序列 。 从转换"Hello World"bool是一个标准的转换序列 。 该标准规定一个标准转换序列总是比一个用户定义的转换序列(§13.3.3.2/ 2)更好:

一个标准转换序列(13.3.3.1.1)大于用户定义的转换序列或省略号转换序列更好的转换序列

这种“更好的转换序列”分析每个可行函数的每个参数做(和你只有一个参数)和更好的功能是通过重载决议选择。

如果你想确保std::string版本叫做,你需要给它一个std::string

Output::Print(std::string("Hello World"));


Answer 2:

FWIW,它可以解决这个问题的方法(如果可以使用的模板),如果你不希望添加重载const char*

#include <iostream>
#include <string>
#include <type_traits>

template <typename Bool,
          typename T = std::enable_if_t<std::is_same<Bool, bool>{}>>
void foo(Bool)
{
  std::cerr << "bool\n";
}

void foo(const std::string&)
{
  std::cerr << "string\n";  
}

int main()
{
  foo("bar");
  foo(false);
}


Answer 3:

不知道为什么没有人张贴了这个,但是你可以添加从为const char *转换到std另一个重载:: string的为您服务。 这从不必担心这节省了来电。

class Output
{
public:
    static void Print(bool value)
    {
        std::cout << value ? "True" : "False";
    }

    static void Print(std::string value)
    {
        std::cout << value;
    }

    // Just add the override that cast to std::string
    static void Print(const* char value)
    {
        Output::Print(std::string(value));
    }
};


文章来源: String literal matches bool overload instead of std::string