Das Zeichenfolgenliteral stimmt mit der bool-Überladung anstelle von std::string überein

Lesezeit: 4 Minuten

Das Zeichenfolgenliteral stimmt mit der bool Uberladung anstelle von stdstring uberein
Matthäus Layton

Ich versuche, eine C++-Klasse zu schreiben, die einige überladene Methoden hat:

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

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

Nehmen wir nun an, ich rufe die Methode wie folgt auf:

Output::Print("Hello World");

das ist das Ergebnis

Wahr

Warum also, wenn ich definiert habe, dass die Methode boolesche und Zeichenfolgen akzeptieren kann, verwendet sie die boolesche Überladung, wenn ich einen nicht booleschen Wert übergebe?

EDIT: Ich komme aus einer C#/Java-Umgebung, also ziemlich neu in C++!

  • @meh, weil sie keine Instanzfunktionen sind.

    – Matthew Layton

    8. Februar 2013 um 10:18 Uhr


  • dein const char* ist eine Heraufstufung des nativen Typs zu bool und eine Heraufstufung des konstruierten Werttyps zu std::string. Was würde Sie wählen. ? Jetzt raten Sie mal welche Compiler gewählt..

    – WhozCraig

    8. Februar 2013 um 10:18 Uhr


  • Sie übergeben ein konstantes Zeichen *, keinen String, versuchen Sie Output::Print(std::string(“Hello World”))

    – jmetcalfe

    8. Februar 2013 um 10:19 Uhr

  • Bezüglich “statisch”: In C++ können Funktionen von der Tyrannei des Klassensystems befreit werden, sodass Sie keine Quasi-Klassen erstellen müssen, wie Sie es in Java tun müssen.

    – molbnilo

    8. Februar 2013 um 10:50 Uhr

  • @molbdnilo, ja, mir ist bewusst, dass Sie klassenlose Funktionen haben können, ein bisschen wie JavaScript, denke ich, wo Funktionen nicht an einen Prototyp gebunden sein müssen … wieder, da ich neu in C++ bin, bin ich mir nicht sicher, was ist hier die beste Praxis.

    – Matthew Layton

    8. Februar 2013 um 11:55 Uhr

Das Zeichenfolgenliteral stimmt mit der bool Uberladung anstelle von stdstring uberein
Josef Mansfeld

"Hello World" ist ein String-Literal vom Typ “Array of 12 const char” die in einen “Zeiger auf umgewandelt werden kann const char” was sich wiederum in a umwandeln lässt bool. Genau das passiert. Der Compiler zieht dies der Verwendung vor std::stringDer Konvertierungskonstruktor von .

Eine Konvertierungssequenz, die einen Konvertierungskonstruktor beinhaltet, wird als a bezeichnet benutzerdefinierte Konvertierungssequenz. Die Umstellung von "Hello World" zu einem bool ist ein Standard-Konvertierungssequenz. Der Standard besagt, dass eine Standard-Konvertierungssequenz immer besser ist als eine benutzerdefinierte Konvertierungssequenz (§13.3.3.2/2):

eine standardmäßige Konvertierungssequenz (13.3.3.1.1) ist eine bessere Konvertierungssequenz als eine benutzerdefinierte Konvertierungssequenz oder eine Auslassungs-Konvertierungssequenz

Diese Analyse der “besseren Konvertierungssequenz” wird für jedes Argument jeder brauchbaren Funktion durchgeführt (und Sie haben nur ein Argument) und die bessere Funktion wird durch Überladungsauflösung ausgewählt.

Wenn Sie sichergehen wollen, dass std::string Version aufgerufen wird, müssen Sie ihr eine geben std::string:

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

  • @LuchianGrigore Ich stimme zu, dass dies die tiefere Frage ist. Ich bin mir nur nicht sicher, ob das OP überhaupt weiß, dass er es gefragt hat = P

    – WhozCraig

    8. Februar 2013 um 10:20 Uhr

  • Ja, ich habe das versucht, was funktioniert hat … scheint nur unordentlich zu sein! Ich habe die Methodendeklaration in Print (const char * value) geändert, was auch zu funktionieren scheint … Ich bin mir jedoch nicht sicher, was hier die beste Vorgehensweise ist!

    – Matthew Layton

    8. Februar 2013 um 10:22 Uhr

  • @series0ne Sie können tatsächlich beide Überladungen haben – an std::string (oder besser const std::string&) und weiter const char*.

    – Angew ist nicht mehr stolz auf SO

    8. Februar 2013 um 10:45 Uhr

  • Wie man einen Fehler oder eine “korrekte” (im Sinne von erwartet) Übersetzung erzwingt, wenn jemand anruft Output::Print("Hello World") was übersetzt wird Output::Print(bool value) das ist nicht das, was jemand erwartet?

    – kirsche40

    17. Februar 2014 um 14:03 Uhr

  • Wissen Sie, ob es einen Unterschied bei der Entscheidung gibt, die Standardkonvertierung zwischen verschiedenen Versionen von C++ durchzuführen? dh. Führen C++17 und C++98 die Standardkonvertierung von const char * in bool in genau denselben Fällen durch?

    – Burgito

    24. Januar 2020 um 8:13 Uhr


1646255407 952 Das Zeichenfolgenliteral stimmt mit der bool Uberladung anstelle von stdstring uberein
Zachary Canann

Ich bin mir nicht sicher, warum niemand das gepostet hat, aber Sie können eine weitere Überladung hinzufügen, die für Sie von const char* in std::string konvertiert. Dies erspart dem Anrufer diese Sorge.

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

  • ich denke du meinst const char * value für deine Überlastung.

    – Eva Hendler

    26. Oktober 2020 um 18:48 Uhr

  • Behoben, Ty Evan.

    – Zachary Canann

    26. Oktober 2020 um 18:53 Uhr

1646255408 432 Das Zeichenfolgenliteral stimmt mit der bool Uberladung anstelle von stdstring uberein
Akim

FWIW, es kann auf diese Weise angesprochen werden (wenn Vorlagen verwendet werden können), wenn Sie keine Überladungen für hinzufügen möchten 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);
}

1646255408 251 Das Zeichenfolgenliteral stimmt mit der bool Uberladung anstelle von stdstring uberein
Замфир Йончев

Seit C++14 haben wir die operator""s von dem std::string_literals Namespace, der verwendet werden kann, um dem Compiler mitzuteilen, dass er an die binden soll string (oder string_view in C++17) überladen:

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

Drucke: Hello World

916160cookie-checkDas Zeichenfolgenliteral stimmt mit der bool-Überladung anstelle von std::string überein

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy