optionale const reference auf nullptr setzen funktioniert, aber warum?
-
Was SeppJ wohl meinte: "Die Konvertierung von
nullptr
nachbool
funktioniert weilnullptr
in einen Zeiger konvertiert werden kann [das ist falsch, denn dann wäre die Konvertierung mehrdeutig], und die konvertieren nachbool
. Wenn letzteres verboten wird, dann funktioniertif (ptr)
nicht mehr."
-
hustbaer schrieb:
Und davon abgesehen, um es zu erlauben hätte auch ein expliziter
operator bool
gereicht (if (expression)
gilt ja als explizite Konvertierung nach bool).Bin also auch etwas überrascht dass hier implizit konvertiert wird.
Ich nicht. Warum sollten sich null pointer values und pointer unterschiedlich benehmen, wenn ich sie einem
bool
zuweise? Gerade das wäre verwirrend.
-
C++14 präzisiert, dass die Konvertierung nur im Kontext einer Direktinitialisierung zulässig ist (wobei die genaue Bedeutung dieser Regel auch nicht völlig glasklar zu sein scheint #1781).
Kurzer Test mit g++ (5.4.0,6.3.0,7.1.0): verweigert die Konvertierung für -std=c++11 und -std=c++14 und -std=c++17
clang 4.0.0: führt die Konvertierung durch für alle Versionen, warnt aber auch in allen Fällen.
-
Hmm. Im Nachhinein macht es doch Sinn. Schließlich war einer der motivierenden Gründe overload resolution:
void f(bool); void f(int*); f(nullptr); // call #2
Implizite Konvertierung nach
bool
würde zumindest dieses Beispiel brechen.
-
Arcoth schrieb:
Hmm. Im Nachhinein macht es doch Sinn. Schließlich war einer der motivierenden Gründe overload resolution:
void f(int); void f(int*); f(nullptr); // call #2
Implizite Konvertierung nach
bool
würde alle arithmetischen Typen mit sich ziehen. In diesem Beispiel wäre das egal, weil die zweite SCS in der UCS für #1 schlechter wäre (Promotion statt Identität). Aber es wäre trotzdem nicht gewollt, dassnullptr
das Verhalten aufweist.Eine Standardkonvertierungssequenz kann nur maximal eine "richtige" Konvertierung haben (der Kram, der gleich am Anfang des Kapitels (jetzt 7 Standard Conversions) steht).
nullptr_t->bool->int geht nicht in einer einzigen Sequenz.
-
Ja, ich hatte zu pragmatisch gedacht;
nullptr_t
ist keine Klasse. Allerdings hast du den Edit verpasst. :p
-
Wenn mich mein Geächtnis nicht täuscht, war u.a. auch genau dieses Beispiel eines, um motivierend zu zeigen, warum nullptr_t als Klasse nicht funktioniert (um NULL zu ersetzen), und direkte Unterstützung durch den Sprachkern erforderlich ist. Wer Lust hat, kann sich ja das entsprechende Paper zu Gemüte führen, ist ja nur ein paar Klicks entfernt.
-
camper schrieb:
Wenn mich mein Geächtnis nicht täuscht, war u.a. auch genau dieses Beispiel eines, um motivierend zu zeigen, warum nullptr_t als Klasse nicht funktioniert (um NULL zu ersetzen), und direkte Unterstützung durch den Sprachkern erforderlich ist.
Weil explizite Konvertierungsoperatoren nicht standardisiert waren? Oder weil ein Konvertierungsoperator-Template in overload resolution einem non-template Konverierungsoperator per se unterliegt? Ich frage mich, ob man letzteres durch ein Template mit default argument lösen könnte.
-
Arcoth schrieb:
camper schrieb:
Wenn mich mein Geächtnis nicht täuscht, war u.a. auch genau dieses Beispiel eines, um motivierend zu zeigen, warum nullptr_t als Klasse nicht funktioniert (um NULL zu ersetzen), und direkte Unterstützung durch den Sprachkern erforderlich ist.
Weil explizite Konvertierungsoperatoren nicht standardisiert waren? Oder weil ein Konvertierungsoperator-Template in overload resolution einem non-template Konverierungsoperator per se unterliegt? Ich frage mich, ob man letzteres durch ein Template mit default argument lösen könnte.
u.a. Das Problem mit NULL wurde ja schon diskutiert, bevor C++ überhaupt standardisiert wurde.
Nachdem ich nochmal die entsprechenden Teile rausgesucht habe (N2431 #654 N2656), muss ich feststellen, dass ich mich wahrscheinlich getäuscht habe. Eventuell habe ich das mit einer Diskussion über bool-Konvertierungen für Smartpointer verwechselt (bevor es explizite Konvertierungsoperatoren gab) - da war es so dass dieser unspecified-bool am Besten (die beste Variante von mehreren schlechten Lösungen, wohlgemerkt) ein Zeiger auf Member(funktion) ist, damit nicht so komische Sachen wie:smart_ptr p; p*42;
möglich sind.
-
SeppJ schrieb:
Dann viel Spaß, wenn du demnächst überall
if(pointer != nullptr)
schreibst, anstattif(pointer)
.Auch wenn das nicht deine Welt ist: Bin kein Freund von impliziten Typumwandlungen und schreibe so etwas tatsächlich meist explizit aus - obwohl mir
die impliziten Umwandlungen bekannt sind und ich weiss dass es nicht nötig wäre. Vorteil: Im Zweifelsfall lässt sich direkt aus dem Code ablesen, dass die
Umwandlung so gewollt war und sich jemand Gedanken darüber gemacht hat. Weniger schreiben zu müssen empfand ich beim Programmieren noch nie als
großen Vorteil, da zumindest bei mir die meiste Zeit nicht fürs Tippen draufgeht