C ++:避免​​在重载时将字符串自动转换为bool

时间:2018-12-10 15:49:33

标签: c++ overload-resolution

我想创建一组方法,这些方法将根据其类型以特殊格式输出值。当我以这种方式进行操作时,到目前为止看起来还不错:

static void printValue(std::ostringstream& out, int value) {
    out << value;
}

static void printValue(std::ostringstream& out, double value) {
    out << value;
}

static void printValue(std::ostringstream& out, const std::string& value) {
    out << "\"" << escapeString(value) << "\"";
}

测试:

printValue(std::cout, 123);    // => 123
printValue(std::cout, 3.14);   // => 3.14
printValue(std::cout, "foo");  // => "foo"

但是,一旦我添加了bool超载:

static void printValue(std::ostringstream& out, bool value) {
    out << (value ? "true" : "false");
}

...事情中断了,因为默认情况下添加字符串调用会使用基于bool的重载:

printValue(std::cout, 123);    // => 123
printValue(std::cout, 3.14);   // => 3.14
printValue(std::cout, true);   // => true
printValue(std::cout, "foo");  // => true <= !!!

有什么办法可以逃脱这种自动强制转换并强制编译器为字符串选择正确的方法吗?

2 个答案:

答案 0 :(得分:3)

您可以添加模板重载,该重载引用大小为char的{​​{1}}数组,其中N是模板参数,和/或接受{{1} }。

N

答案 1 :(得分:3)

为什么会这样:

当编译器试图选择“最佳”函数来调用给定的某些参数时,它会以这种方式大致确定重载集的优先级:

  1. 完全匹配:例如,如果您传递一个const char*并且该函数接受一个const char*,那就太好了
  2. 标准转换顺序:例如,将const char[4]转换为const char*,然后将const char*转换为bool(基于对nullptr的检查) 。或将short提升为int
    • 这些转换也有其自己的优先级,为简洁起见,我们可以忽略
  3. 用户定义的转换:基本上是(通过构造函数或转换运算符)转换为某些非fundamental type

因为要提供字符文字"foo",所以它具有从const char[4]const char*的标准转换序列(通过数组到指针的转换,请参见[conv.array]),然后从通过布尔转换从const char*bool(请参见[conv.bool])。

因此,虽然可以通过用户定义的转换用const std::string&来构建"foo",但是这种转换的优先级低于标准转换序列,因此选择了布尔值。 / p>

您可以做什么:

  • 对此进行预见并为const char*const char[N](如@juanchopanza said)写一个重载
  • 在调用函数std::string
  • 时创建一个printValue(std::string{"foo"});