• [^] # Re: nullptr

    Posté par . En réponse à la dépêche Nouveautés du langage C dans sa prochaine version C23. Évalué à 1. Dernière modification le 06 février 2023 à 11:52.

    Pas besoin d'aller chercher un exemple avec des fonctions variadiques puisque C++ permet l'overloading. Une macro NULL définie comme un entier ou comme un void* serait difficile à utiliser de façon consistante.

    #include <iostream>
    #include <cstdlib>
    void func(int x) { std::cout << "integer\n"; }
    void func(long x) { std::cout << "long\n"; }
    void func(long long x) { std::cout << "long long\n"; }
    void func(void*x) { std::cout << "void pointer\n"; }
    void func(int*x) { std::cout << "int pointer\n"; }
    void func(std::nullptr_t x) { std::cout << "nullptr\n"; }
    template <typename T> void func(T *x) { std::cout << "template pointer " << x << "\n"; }
    int main(void) {
     func(0);
     func(0l);
     func(0ll);
     func((void*)0);
     func((int*)0);
     func(nullptr);
     func(NULL);
     return 0;
    }
    

    Dans g++, NULL est une constante interne __null avec un type indéfini qui est probablement proche de long. G++ appelle donc la version 'long' pour func(NULL) avec toutefois un joli warning car il sait que ce n'est probablement pas ce que souhaite l'utilisateur.

    nullptr a son propre type nullptr_t avec ses propres règles de résolution pour affiner les règles de résolutions. Il est compatible avec tout les pointeurs mais uniquement quand il n'y a pas d'ambiguité. Dans exemple, func(nullptr) ne peut appeler func(void *) ou func(int *) que si une seule des deux fonctions est présente. Par contre 'nullptr_t' n'est pas compatible avec les types template 'T*' et les types entiers.