String literal coincide con bool overload en lugar de std:: string


Estoy tratando de escribir una clase de C++ que tiene algunos métodos sobrecargados:

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

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

Ahora digamos que llamo al método de la siguiente manera:

Output::Print("Hello World");

Este es el resultado

Verdadero

Entonces, ¿por qué, cuando he definido que el método puede aceptar booleano y string, utiliza la sobrecarga booleana cuando paso un valor no booleano?

EDIT: Vengo de un entorno C # / Java, ¡muy nuevo en C++!

Author: M.M, 2013-02-08

2 answers

"Hello World" es un literal de cadena de tipo " array of 12 const char" que se puede convertir en un "puntero a const char" que a su vez se puede convertir en un bool. Eso es precisamente lo que está sucediendo. El compilador prefiere esto a usar el constructor de conversión de std::string.

Una secuencia de conversión que involucra a un constructor de conversión se conoce como secuencia de conversión definida por el usuario. La conversión de "Hello World" a bool es una secuencia de conversión estándar . La norma establece que un la secuencia de conversión estándar siempre es mejor que una secuencia de conversión definida por el usuario(§13.3.3.2/2):

Una secuencia de conversión estándar (13.3.3.1.1) es una mejor secuencia de conversión que una secuencia de conversión definida por el usuario o una secuencia de conversión de puntos suspensivos

Este análisis de "mejor secuencia de conversión" se realiza para cada argumento de cada función viable (y solo tiene un argumento) y la mejor función se elige por resolución de sobrecarga.

Si si desea asegurarse de que se llama a la versión std::string, debe darle un std::string:

Output::Print(std::string("Hello World"));
 35
Author: Joseph Mansfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-08 10:23:23

FWIW, se puede direccionar de esta manera (si se pueden usar plantillas), si no desea agregar sobrecargas para 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);
}
 3
Author: akim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-16 12:26:34