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?
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.
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.
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.
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)