8
votes

Pourquoi ne puis-je pas avoir de type de retour covariant avec Void *?

Pourquoi le code suivant est-il une erreur de covariance? N'est-ce pas t * code> covariant avec void * code> ...? xxx pré>

GCC dit: p>

invalid covariant return type for 'virtual int* Derived::foo()'


0 commentaires

3 Réponses :


7
votes

[CLASS.VIRTUAL] / P7, OFFACIQUE MINE:

Le type de retour d'une fonction primordiale doit être soit identique à le type de retour de la fonction remplacée ou covariant avec le classes des fonctions. Si une fonction d :: f remplace une fonction b :: f , les types de retour des fonctions sont covariants si elles satisfaire les critères suivants:

  • Les deux sont des pointeurs à classes , les deux sont des références de lvalue à classes , ou les deux sont des références de rap, ou les deux classes strictes [Note de bas de page omis]
  • [...]

    des pages 294-5 de D & E :

    AFERT Quelque compte de l'alternative, nous avons décidé de permettre Remplacement d'un B * par un d * et d'un B & par un d & b < / code> est un Base accessible de d . De plus, const peut être ajouté ou soustraite partout où c'est sûr. Nous avons décidé de ne pas détendre les règles à permettre des conversions techniquement réalisables telles qu'un d à un accessible base b , un d à un x pour lequel d a une conversion, int * à void * , double à int , etc. Nous avons senti que les avantages de permettant de telles conversions par le dépassement ne l'emporteraient pas la Coût de mise en œuvre et potentiel d'utilisateurs déroutants.


3 commentaires

Serait bien si vous pouviez expliquer le "pourquoi" derrière cette conception.


@Mehrdad a ajouté une citation de D & E.


Lorsque je regarde le problème avec la covariance et les limites des espaces de noms en C ++, je peux discerner le raisonnement derrière l'objet et les paquets de Java.



-1
votes

La fonction de type de retour Covariant est lorsque, une classe dérivée fournit un type de retour plus spécifique / plus étroit pour une fonction remplacée. Le type de retour de classe dérivé est dit covarient.

int * n'est pas de type vide * alors que quelque chose comme celui-ci représente le type de retour Covariant: P>

struct Base {
  virtual void *foo();
  virtual Base* func();
};
struct Derived : Base {
//  int *foo();
  Derived* func(); //COVARIANT RETURN TYPE
};


1 commentaires

Vous expliquez la définition de "covariance", l'OP demande "pourquoi".



1
votes

La covariance entre void * et t * n'est pas autorisé car:

1. Manque de cohérence .

Le mode de covariance actuel est trivial de comprendre et ne crée pas de confusion.
Imaginez simplement de Void * type de covariance est autorisé. Pour une étape de dérivation, c'est bien, mais cela créera une confusion. par exemple: xxx

dans la 3ème hiérarchie de struct double _ , l'utilisateur sera confus que même si double * à int * n'est pas possible, pourquoi le code est toujours compilé? Seulement après avoir vérifié le haut de la classe Void _ , il est connu qu'il est dû à double * à vide * est "Covariant". Les mêmes choses vont aussi pour le compilateur: -)

2. Problème avec les références

en cas de classes, retourner B & / d * / dd * est possible. Mais la même chose n'est pas possible avec void & et donc int & etc.

3. Mélange de covarcarces

si vide * est autorisé, alors suivi est également autorisé de manière non intentionnelle. xxx

qui ajoute jusqu'à confusion.


0 commentaires