2017-09-29 9 views
5

J'écris un code dans lequel le type de retour d'une fonction est plutôt compliqué. Je voudrais utiliser auto pour en déduire le type de retour, mais ce n'est évidemment pas possible dans une déclaration forward. Donc, j'espérais au moins double emploi avec le contenu de la déclaration de retour et procédez comme suit,Conflit entre le type de retour et la déduction de type retour

int q = 5; // veeery complicated type 

/* Declaration - the best we can do */ 
auto f() -> decltype(q); 

/* Later, in a different file */  
auto f() { 
    return q; 
} 

Cela produit l'erreur suivante dans GCC 7,

error: ambiguating new declaration of ‘auto f()’ 
note: old declaration ‘int f()’ 

Bien sûr, je pourrais répéter

dans la définition (qui fonctionne), mais pourquoi devrais-je besoin lorsque le type de retour est déjà uniquement donné par l'instruction return? Comment est le type de f dans ma définition finalement plus ambigu que int f()?

+0

pas un gourou standard, mais ce qui est le compilateur censé faire si , selon votre définition actuelle de la fonction, le type de fin et le type déduit 'auto' ne correspondent pas? Je pense que c'est la raison pour laquelle gcc le signale. – YiFei

+1

Je m'attendrais à ce que ça me dise simplement que ça ne correspond pas. Si deux types sont identiques ou non, il devrait être facile de répondre. Mais maintenant que vous mentionnez ceci, très intéressant, l'erreur produite par 'int f(); long f() {return 1; } 'est libellé de la même manière! –

+0

Je serais d'accord avec vous. J'aimerais aussi savoir s'il existe une référence standard qui indique explicitement qu'un type de retour déduit par auto ne peut pas être plié avec une fonction de type de retour concrète (même s'ils correspondent). – YiFei

Répondre

8

Le problème ici est qu'un retour arrière n'est pas le même que le type de retour purement déduit. Dans [dcl.spec.auto]/2

[...] Si la fonction declarator comprend un retour-arrière de type (8.3.5), qui spécifie le type de retour de la fonction déclarée

Alors

auto f() -> decltype(q); 

est vraiment

int f(); 

qui est différent de

auto f() 

Il est également [dcl.spec.auto]/13

redéclarations ou spécialisations d'une fonction ou d'un modèle de fonction avec un type de retour déclaré utilise un type d'espace réservé doit utiliser également cet espace réservé, pas un type déduit. [Exemple:

auto f(); 
auto f() { return 42; } // return type is int 
auto f();    // OK 
int f();     // error, cannot be overloaded with auto f() 
decltype(auto) f();  // error, auto and decltype(auto) don’t match 

Ce qui est un peu opposé de ce qui se passe ici, mais il n'exemplifient plus que ce n'est pas permis