32 votes

Pourquoi puis-je utiliser operator = mais pas operator == avec les initialiseurs d'attache C ++ 11?

Voir cet exemple:

 struct Foo
{
    int a;
    int b;

    bool operator == (const Foo & x)
    {
        return a == x.a && b == x.b;
    }
};

int main ()
{
    Foo a;

    a = {1, 2};

    if (a == {1, 2}) // error: expected primary-expression before ‘{' token
    {
    }
}
 

La ligne a={1,2} est correcte. Les accolades sont converties en Foo pour correspondre au type d'argument de la méthode implicite operator= . Cela fonctionne toujours si operator= est défini par l'utilisateur.

La ligne if (a=={1,2}}) erreurs comme indiqué.

Pourquoi l'expression {1,2} pas convertir en Foo pour correspondre à la défini par l' utilisateur operator== méthode?

41voto

Andy Prowl Points 62121

Liste d'initialisation ne peut pas être utilisée comme argument d'un opérateur dans le cas général. Conformément à l'Alinéa 8.5.4/1 du C++11 Standard:

[...] La liste d'initialisation peut être utilisé

- comme l'initialiseur, dans une définition de variable (8.5)

- comme l'initialiseur dans une nouvelle expression (5.3.4)

- dans une instruction de retour (6.6.3)

- une gamme d'initialiseur (6.5)

- comme un argument de fonction (5.2.2)

- comme un indice (5.2.1)

- comme d'un argument à un constructeur invocation (8.5, 5.2.3)

- comme un initialiseur pour un non-membre de données statiques (9.2)

- dans un mem-initialiseur (12.6.2)

- sur le côté droit d'une affectation (5.17)

Le dernier élément explique pourquoi la liste d'initialisation est autorisé sur le côté droit de l' operator =, même si il n'est pas permis, en général, à l'arbitraire d'un opérateur.

En raison de la cinquième élément ci-dessus, cependant, il peut être utilisé comme un argument à une fonction régulière d'appel, de cette façon:

if (a.operator == ({1, 2}))

7voto

C'est juste simplement pas pris en charge.

Initialiseur de listes sont explicitement définis pour être valides dans les initialisations ([C++11: 8.5.4]), et les attributions de:

[C++11: 5.17/9]: Un arc-boutée-init-liste peut apparaître sur le côté droit de

  • une affectation à un scalaire, auquel cas l'initialiseur de liste à un seul élément. Le sens de l' x={v}T est le type scalaire de l'expression x, est celui de l' x=T(v) sauf que pas de rétrécissement de conversion (8.5.4) est autorisée. Le sens de l' x={} est x=T().
  • une mission définie par l'utilisateur défini par l'opérateur d'affectation, auquel cas la liste d'initialiseur est passé comme argument à la fonction opérateur.

Il n'existe pas de standard pour permettre à d'autres, de l'arbitraire des cas.

S'il lui était permis, dans cet exemple, le type d' {1,2} serait assez ambiguë. Il serait compliqué de la langue élément à mettre en œuvre.

4voto

johnchen902 Points 5903

Un casting explicite est requis.

 if (a == (Foo){1, 2})
{
}
 

0voto

mohit Points 84

Lorsque vous utilisez l'expression contenant le type défini par l'utilisateur, une fonction opérateur surchargée et == est appelée, laquelle, conformément à la définition que vous avez donnée, requiert un argument de référence d'un objet de classe Foo.

donc votre expression devrait être comme un == b

où b est un objet de classe Foo

Ici, avec cette expression, vous pourrez comparer les données des membres de b et a et donc savoir si elles sont égales ou non.

0voto

6502 Points 42700

Pas de véritable raison.

C++ est le résultat d'un comité d'efforts, donc parfois étrange mais la décision délibérée peut passer à travers en raison de la complexité politique et sociologique de la dynamique.

Syntaxe C++ est dur. Très dur. Presque incroyablement dur. Il y a des règles vont même comme "si vous pouvez analyser cette arbitrairement longue séquence de jetons à la fois comme ceci ou cela, alors il est présent".

Il a fallu de nombreuses années pour les compilateurs même simplement d'accord sur ce qu'est le C++, et ce qui ne l'est pas.

Dans ce cas, mon sauvage imagine qu'ils n'aimaient pas l'idée que les cas qui paraissent très semblables:

MyClass x = {...};
MyClass y; y = {...};

seraient traités différemment donc il y a une disposition spéciale pour l'affectation à permettre à la syntaxe.

À partir d'un point de vue technique, je ne vois pas quels sont les problèmes que de le laisser à d'autres opérateurs, et d'autre part, si il y a des problèmes (par exemple pour la surcharge, l'instanciation d'un modèle etc.) Je ne vois pas comment la cession de l'espoir de leur échapper.

MODIFIER

g++ permet d'utiliser non seulement le strict operator= mais aussi operator+=, operator-= et similaires "augmentée" d'assignation. Peut-être les problèmes de logique qui se produit uniquement si vous permettre aux non-membres de surcharges (qui sont interdites pour l'affectation et augmentée de l'affectation des opérateurs).

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