字符串文字匹配bool重载而不是std :: string

时间:2013-02-08 10:16:01

标签: c++ string boolean overloading overload-resolution

我正在尝试编写一个包含一些重载方法的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 ++来说还是新手!

4 个答案:

答案 0 :(得分:40)

"Hello World"是“12 const char数组”类型的字符串文字,可以转换为“指向const char的指针”,然后可以转换为{{1 }}。这正是发生的事情。编译器更喜欢使用bool的转换构造函数。

涉及转换构造函数的转换序列称为用户定义的转换序列。从std::string"Hello World"的转换是标准转换序列。该标准规定标准转换序列总是优于用户定义的转换序列(§13.3.3.2/ 2):

  

标准转换序列(13.3.3.1.1)是比用户定义的转换序列或省略号转换序列更好的转换序列

对每个可行函数的每个参数进行“更好的转换序列”分析(并且只有一个参数),并且通过重载决策选择更好的函数。

如果您想确保调用bool版本,则需要为其提供std::string

std::string

答案 1 :(得分:3)

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);
}

答案 2 :(得分:1)

从 C++14 开始,我们有 operator""s 命名空间中的 std::string_literals,它可用于告诉编译器绑定到 string(或 string_view C++17) 重载:

using namespace std::string_literals;
Output::Print("Hello World"s);

打印:Hello World

答案 3 :(得分:0)

不确定为什么没有人发布此内容,但是您可以为您添加另一个重载,将其从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));
    }
};