web-dev-qa-db-fra.com

Pourquoi n'est-ce pas une erreur au moment de la compilation de renvoyer un nullptr en tant que chaîne std ::?

En raison d'un bogue, je viens de découvrir que ce code se compile bien avec Visual Studio 17 et probablement aussi avec d'autres compilateurs. Maintenant, je suis curieux de savoir pourquoi?

#include <iostream>
#include <string>

std::string foo(){
    return nullptr;
}

int main(){
    auto s = foo();
    std::cout << s << std::endl;
}

Je pourrais imaginer que c'est parce que le std::basic_string c'tor pourrait être invoqué avec un char* et en renvoyant une conversion implicite de ptr en std::string se produit (avec NULL comme argument, puis passe poof). Suis-je sur la bonne voie?

24
Taron

Oui, votre hypothèse est bonne, la vérification std::basic_string Constructeurs # 5 sera appelée:

basic_string( const CharT* s,
              const Allocator& alloc = Allocator() );

Notez que passer nullptr appelle un comportement indéfini comme indiqué dans la norme et les notes:

Le comportement n'est pas défini si [s, s + Traits::length(s)) n'est pas une plage valide ( par exemple, si s est un pointeur nul ).

24
Sombrero Chicken

Pourquoi ne compilerait-il pas? std::string a le constructeur suivant:

string(const CharT* s, const Allocator& alloc = Allocator());

qui construit la chaîne avec le contenu initialisé avec une copie de la chaîne de caractères terminée par un pointeur pointé par s. Le constructeur est pas explicite, donc la conversion implicite de nullptr en std::string est en effet possible.

13
Evg