45 votes

Quel est le nom complet d'une fonction ami définie à l'intérieur d'une classe?

Quel est le nom complet d'une fonction ami définie à l'intérieur d'une classe?

J'ai récemment vu un exemple analogue au suivant. Quel est le nom complet qualifié de val() ci-dessous?

 #include <iostream>

namespace foo {
    class A {
        int x;
    public:
        A(int x = 0) : x(x) { }

        friend int val(const A &a) { return a.x; }
    };
}

int main() {
    foo::A a(42);

    // val() found using ADL:
    std::cout << val(a) << std::endl;

    // foo::val(a); // error: 'val' is not a member of 'foo'
    // foo::A::val(a); // error: 'val' is not a member of 'foo::A'

    return 0;   
}
 

La recherche dépendante des arguments est-elle le seul moyen de trouver val() ?

Certes, cela ne découle pas d'un problème pratique. Je cherche simplement à mieux comprendre.

35voto

StoryTeller Points 6139

Est argument dépendante de la recherche de la seule façon de val() peut être trouvé?

Oui, c'est le seul moyen. Pour citer le saint standard à [l'espace de noms.memdef]/3:

Si un ami de la déclaration de non-local de la classe de première déclare une classe, fonction, modèle de classe ou de la fonction de modèle de l'ami est un membre d'enfermer les plus secrets de l'espace de noms. L'ami de la déclaration n'est pas par lui-même au nom visible par les non qualifiés de recherche ou un professionnel de la recherche.

Ainsi, alors que val est membre de l' foo, il n'est pas visible à la recherche de l'ami de la déclaration de seul. Une définition de classe (qui est aussi une déclaration) est nécessaire pour la rendre visible. Pour une ligne de définition (et pas de déclaration de classe), cela signifie ADL est le seul moyen pour appeler la fonction.


Comme un bonus supplémentaire, C++ fait une fois que la notion de "l'ami du nom de l'injection". Qui cependant a été supprimé, et les règles pour les AVQ ajusté comme un remplacement. Une présentation plus détaillée peut être trouvée dans WG21 papier N0777 (pdf).

7voto

Rxmsc Points 927

C++ Standard [7.3.1.2/3 (de la norme ISO/IEC 14882:2011)]:

Tout d'abord le nom déclaré dans un espace de noms est un membre de cette espace de noms. Si un ami de la déclaration de non-local de la classe de première déclare une classe ou d'une fonction de l'ami de la classe ou de fonction est un membre de la enfermer les plus secrets de l'espace de noms. Le nom de l'ami n'est pas trouvé par non qualifiés de recherche (3.4.1) ou par du personnel qualifié recherche (3.4.3) jusqu'à ce qu'un de correspondance de déclaration est fourni dans cet espace de noms de la portée (soit avant ou après la définition de la classe de l'octroi de l'amitié). Si un ami la fonction est appelée, de son nom peut être trouvé par la recherche d'un nom qui considère les fonctions des espaces de noms et les classes associées à la les types des arguments de la fonction (3.4.2). Si le nom d'un ami la déclaration est ni qualifiés, ni un modèle d'identité et la déclaration est une fonction ou d'un élaboré un type de prescripteur, de la recherche afin de déterminer si l'entité a été précédemment déclaré ne pas envisager de tout étendues à l'extérieur de l'enfermer les plus secrets de l'espace de noms.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X