c++ - Warum arbeiten char{} und char() als temporäre Variable für ein char*-Argument?




c++14 c++17 (2)

In Visual C ++ 2017 (mit /std:c++14 oder mit /std:c++17 ) funktioniert der folgende Code:

void TakePtr(char*); // const or not

int main()
{ 
     TakePtr(char{});
     TakePtr(char());
}

Ich verstehe nicht, warum es funktioniert.

Anscheinend würde auch Folgendes funktionieren (wie erwartet):

void TakeChar(char);

   TakeChar(char{});
   TakeChar(char());

Wie leitet der Compiler den Typ char zu char* (oder konvertiert ihn), wenn char{} oder char() als Argument verwendet wird?

Wenn ich jetzt sowohl char als auch char* -Überladungen habe, funktioniert das ohne Fehler / Warnung vor Mehrdeutigkeiten:

void TakePtr(char*);
void TakePtr(char);

    TakePtr(char{});  // Chooses 'char'
    TakePtr(char());  // Chooses 'char'

Warum ist der Compiler mit char{} für TakePtr(char*) Ordnung? Und warum wird bei der Auswahl der besseren Version keine Warnung / Fehlermeldung ausgegeben? Ein solches Verhalten kann dazu führen, dass vorhandener Code beschädigt wird.

Sicher ist der Compiler nicht zufrieden mit:

void TakePtr(char*);

    char c{};
    TakePtr(c);

Das liegt einfach daran, dass MSVC im Rückstand ist: In C ++ 03 lautete die Regel, dass jeder konstante Ausdruck vom Typ Integer und Wert 0 eine Nullzeiger-Konstante ist und daher in char* konvertiert werden kann. Sicherlich qualifiziert sich char() - und char{} bedeutet dasselbe, obwohl es sich nie mit der Regel überschneidet.


Weil Visual viel lügt. Besonders älter. Ihr Code fordert Sie auf, einen Fehler zu melden:

<source>:9:6: error: no matching function for call to 'TakePtr'

     TakePtr(char{});

     ^~~~~~~

<source>:5:6: note: candidate function not viable: no known conversion from 'char' to 'char *' for 1st argument

void TakePtr(char*); // const or not

     ^

<source>:10:6: error: no matching function for call to 'TakePtr'

     TakePtr(char());

     ^~~~~~~

<source>:5:6: note: candidate function not viable: no known conversion from 'char' to 'char *' for 1st argument

void TakePtr(char*); // const or not

     ^

2 errors generated.

Visual ist als "Wonky" im Sinne des C ++ - Standards bekannt. Verlassen Sie sich also nicht zu sehr darauf. Versuche es mit clang / gcc, nur um sicherzugehen.





visual-c++-2017