web-dev-qa-db-fra.com

'auto' n'est pas autorisé dans le prototype de fonction avec Clang

Utilisation de Clang 3.5, 3.6 ou 3.7, avec l'indicateur std=c++1y le code suivant ne se compile pas:

#include <iostream>
auto foo(auto bar) { return bar; }
int main() {
  std::cout << foo(5.0f) << std::endl;
}

L'erreur donnée est:

erreur: 'auto' non autorisé dans le prototype de fonction

Je n'ai aucune erreur en utilisant g ++ 4.9. Cette erreur est-elle produite parce que Clang n'a pas encore implémenté cette fonctionnalité ou est-ce parce que je ne suis pas autorisé à le faire et que GCC l'autorise d'une manière ou d'une autre?

21
coincoin

Comme nous le voyons dans le mailing de discussion ISO C++: paramètres decltype (auto) vs transfert parfait les paramètres auto des non-lambdas font partie de concepts lite et donc pas en C + +14:

clang est correct dans le sens où nous n'avons pas encore de paramètres automatiques. Les concepts lite peuvent les apporter, mais C++ 14 n'en a pas.

Si nous utilisons le drapeau - pedantic avec gcc, nous recevons l'avertissement suivant:

warning: ISO C++ forbids use of 'auto' in parameter declaration [-Wpedantic]
  auto foo(auto bar) { return bar; }
           ^

Cela ressemble donc à une extension.

Comme l'a souligné dyp, lambdas polymorphes l'a fait en C++ 14 et autorise les paramètres automatiques, un exemple tiré de l'article:

// 'Identity' is a lambda that accepts an argument of any type and
// returns the value of its parameter.
auto Identity = [](auto a) { return a; };
int three = Identity(3);
char const* hello = Identity("hello");

Qui est d'ailleurs la même fonctionnalité que vous souhaitez implémenter dans votre exemple.

17
Shafik Yaghmour

Bien que votre syntaxe spécifique ne soit pas arrivée en C++ 14, une option similaire qui l'a fait est:

static auto foo = [](auto bar) { return bar; };

qui réalise essentiellement la même chose.

10
M.M

Vous pouvez utiliser un modèle à la place:

template<class A>
A foo(A bar) { return bar; }

Auto n'est autorisé que lorsque le compilateur peut déduire le type du contexte.

3
Thomas Sparber

Le compilateur ne peut pas déduire le type à partir du contexte.

Qu'est-ce qui ne va pas

template<typename Y>
Y foo(Y bar){return bar;}

et devez-vous passer bar par valeur?

Dans votre cas, vous pouvez utiliser la syntaxe type de retour de fin:

auto foo(auto bar) -> decltype(bar)

1
Bathsheba