Question

Il est récemment venu à mon attention que les fonctions membres complètement ombre Fonctions libres avec le même nom quand dans la classe.Et par complètement, je veux dire que chaque fonction libre avec le même nom n'est pas prise en compte pour la résolution de la surcharge du tout.Je peux comprendre pourquoi cela se fait avec quelque chose comme ceci:

void f();

struct S
{
    void f();

    void g()
    {
        f(); // calls S::f instead of ::f
    }
};

où les fonctions ont des signatures identiques, sa seule naturelle que le cadre variable fonctionne de la même manière.Mais pourquoi interdire les appels non ambigieux où la fonction libre a une signature différente comme celle-ci:

void f();

struct S
{
    void f(int x);

    void g()
    {
        f(); // fails to compile attempting to call S::f, which has wrong signature
    }
};

Je ne demande pas comment appeler une fonction gratuite ombreur de l'intérieur de la classe.Ce que je veux savoir, c'est la justification de cette conception.

Était-ce utile?

La solution

Pour la recherche de noms non qualifiée, une seule portée à la fois est envisagée et si la recherche de cette portée ne donne aucun résultat, la dernière portée est recherchée.Dans votre cas, seule la portée de S est recherchée.

Mais pourquoi interdire les appels non ambigieux où la fonction libre a une signature différente comme celle-ci:

Le problème est que nom de nom ne concerne rien que le nom, l'identifiant .Il est complètement inconscient du fait que vous souhaitez appeler une fonction, il vient de voir un identifiant.Le même nom de nom de nom se produit si vous utilisez simplement auto x = f;, et si vous en pensez de cette façon, il y a de très bonnes raisons pour lesquelles vous ne voulez qu'à une portée très limitée de rechercher.Tout ce qui pourrait simplement surprendre l'utilisateur.

Autres conseils

Il existe une règle spéciale, très surprenante (mais elle ne s'applique pas à votre exemple) indiquant qu'une fois qu'un numéro de membre de classe est trouvé par nom de recherche, aucun espace d'espace de noms n'est recherché:

#include <string>

struct C {
    std::string s;

    explicit C (std::string);

    void swap (C& rhs) {
        swap (s, rhs.s); // error: swap is C::swap
    }   
};

void swap (C& lhs, C& rhs) {
    swap (lhs.s, rhs.s); // std::swap(string,string)
}

imo, c'est la folie.

Mais pourquoi interdire les appels non ambigieux où la fonction libre a une signature différente comme celle-ci:

Recherche de noms se produit avant la surcharge de la résolution:

  • Si la recherche est ambiguë, la résolution de surcharge n'est pas terminée.
  • Si aucune fonction viable n'est trouvée à la recherche de noms, aucune autre partie de la recherche n'est essayée.

Les règles sont suffisamment complexes sans "retour" entre surcharge et recherche de noms.Je suggérerais de simplifier (comme supprimant la règle de nom de la portée de l'espace de noms de noms de noms de noms, et supprimez la recherche de nom ambiguë) plutôt que de complexification.

Je ne peux pas fournir une réponse faisant autorité (peut-être que des souvenirs d'une citation de Design and Evolution of C++ ou ont été en réalité sur le comité à cette époque), mais ma première hypothèse serait d'échouer exactement dans les cas comme vous le montre.Il est facile d'oublier combien de choses sont en portée à une certaine période.La résolution de surcharge supplémentaire peut être assez complexe et il peut y avoir des arguments et une conversion par défaut.Je préfère donc avoir la portée la plus limitée dans ce cas pour être toujours sûr de ce que l'on appelle exactement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top