2017-04-26 1 views
2

Je m'excuse de ne pas avoir assez de temps pour faire une enquête approfondie et de compter sur votre aide à la place.C++ 14 + déduction de type automatique pour l'argument avec la valeur par défaut

Tenir compte du code simple:

#include <iostream> 

enum class PrintColour 
{ 
    COLOUR_1  = 0, 
    COLOUR_2  = 1, 
}; 

void colour(auto c = PrintColour::COLOUR_1) 
{ 
    switch (c) 
    { 
     case PrintColour::COLOUR_1: 
      std::cout << "Colour 1" << std::endl; 
      break; 
     case PrintColour::COLOUR_2: 
      std::cout << "Colour 2" << std::endl; 
    } 
} 

int main() 
{ 
// colour(); couldn't deduce template parameter ‘auto:1’ 
    colour(PrintColour::COLOUR_1); // Fine! 
} 

Ce code exactement comme il est compile, et fonctionne sans problème. Si je le décommenter colour();, cependant, g ++ déclenche l'erreur:

auto_param.cpp: In function ‘int main()’: 
auto_param.cpp:27:10: error: no matching function for call to ‘colour()’ 
    colour(); 
     ^
auto_param.cpp:13:6: note: candidate: template<class auto:1> void colour(auto:1) 
void colour(auto c = PrintColour::COLOUR_1) 
     ^~~~~~ 
auto_param.cpp:13:6: note: template argument deduction/substitution failed: 
auto_param.cpp:27:10: note: couldn't deduce template parameter ‘auto:1’ 
    colour(); 
     ^

Il est possible que je manque juste un point stupide ou il est possible que je suis vraiment stupide et mal compris la chose.

Dois-je être en mesure de déclarer un paramètre de fonction comme auto tout en étant capable de lui donner une valeur par défaut en C++ 11 ou C++ 14? Je pensais que la valeur par défaut donnée serait suffisante pour permettre au compilateur de déduire le type de paramètre ...

Merci d'avance.


EDIT 1:

Il pense que je dois faire ma question plus claire afin de ne pas être confondu par Is there a way to pass auto as an argument in C++?

Le point ne passe pas ici auto à une fonction mais ayant auto en conjonction avec une valeur par défaut pour l'argument, quelque chose de non pris en compte dans la question susmentionnée.

EDIT 2:

Comme précisé dans les commentaires ici, C++ 11 ne dispose pas d'une telle caractéristique de passage auto comme paramètre, mais 14 C++ et (g ++ 6.3.1 par défaut « gnu ++ 14 ") semble. Ma question originale n'est pas liée à C++ 11, cependant, et ma question n'est pas si C++ 11 soutient les paramètres auto. Je comptais sur auto comme paramètre mais j'ai oublié de vérifier la version standard minimum pour cela. Mes excuses et je l'ai réparé maintenant.

g++ -std=c++11 auto_param.cpp -o auto_param 
auto_param.cpp:13:14: error: use of ‘auto’ in parameter declaration only available with -std=c++14 or -std=gnu++14 

j'espère qu'il soit clair que la différence entre ma question et Is auto as a parameter in a regular function a GCC 4.9 extension?. S'il vous plaît dites-moi si non.

+0

double possible de [Y at-il un moyen de passer automatique comme un argument en C++?] (http://stackoverflow.com/questions/29944985/is-there-a-way-to- pass-auto-as-an-argument-in-c) –

+2

* En supposant que * 'auto' est juste un sucre syntaxique pour le paramètre template, vous ne pouvez pas appeler cette fonction sans arguments, car son type de paramètre ne peut pas être déduit dans ce le contexte. –

+0

Possibilité de duplication de [Est auto comme paramètre dans une fonction régulière une extension GCC 4.9?] (Http://stackoverflow.com/questions/25879705/is-auto-as-a-parameter-in-a-regular-function -a-gcc-4-9-extension) – cpplearner

Répondre

2

Should I be able to declare a function parameter as auto while still being able to give it a default value in C++11 or C++14?

Je ne sais pas si le support 17 C++, mais, en ce que je sais, C++ 11 et 14 C++ ne prend pas en charge un paramètre auto pour une fonction (C++ 14 support seulement pour les fonctions lambda)

I thought the given default value would be enough to let compiler deduce the parameter type...

Si au lieu de auto vous acceptez d'utiliser un type de modèle, vous devez ajouter le type de modèle par défaut également.

Quelque chose comme suit

template <typename T = decltype(PrintColour::COLOUR_1)> 
void colour(T c = PrintColour::COLOUR_1) 
{ 
    switch (c) 
    { 
     case PrintColour::COLOUR_1: 
      std::cout << "Colour 1" << std::endl; 
      break; 
     case PrintColour::COLOUR_2: 
      std::cout << "Colour 2" << std::endl; 
    } 
} 

Je sais: est redondant.

- EDIT -

L'OP dit

I was just wondering if I couldn't make my code more readable by not repeating

Plus lisible probablement pas, mais ... si vous le voulez pas répéter ... Je sais que les macros sont distillés, mais le mal ... si vous voulez vraiment éviter de répéter ...

#define noRepeat(r, n, a, b) \ 
r n (decltype(b) a = b) 

noRepeat(void, colour, c, PrintColour::COLOUR_1) 
{ 
    switch (c) 
    { 
     case PrintColour::COLOUR_1: 
      std::cout << "Colour 1" << std::endl; 
      break; 
     case PrintColour::COLOUR_2: 
      std::cout << "Colour 2" << std::endl; 
    } 
} 

ou encore (si vous voulez faire le tour sur base de paramètres)

#define parDef(a, b) decltype(b) a = b 

void colour (parDef(c, PrintColour::COLOUR_1), parDef(d, 5)) 
{ 
    switch (c) 
    { 
     case PrintColour::COLOUR_1: 
      std::cout << "Colour 1" << std::endl; 
      break; 
     case PrintColour::COLOUR_2: 
      std::cout << "Colour 2" << std::endl; 
    } 
} 
+0

Thanks @ max66. Je me demandais juste si je ne pouvais pas rendre mon code plus lisible en ne répétant pas '(PrintColour c = PrintColour :: COLOUR_1)'. Je sais que cela n'a pas fonctionné, mais je veux toujours apprendre pourquoi (et peut-être apprendre une autre façon de ranger mon code aussi bien). A partir de @Igor R. comment, je considérais 'auto' comme du" sucre syntaxique ". – j4x

+1

@fljx - Je vois ... eh bien ... si vous voulez éviter de répéter ... réponse améliorée. – max66

+0

Votre modification est tentante ... Je considère quelque chose comme '#define \t def_deduce (p, def_value) \t decltype (valeur de def) p = def_value' et plus tard' couleur void (def_deduce (c, PrintColour :: COLOUR_1)) 'mais , comme vous l'avez dit. les macros sont ignominieuses. Dernière note, d'après g ++, il semble que C++ 14 supporte 'auto' comme paramètre. – j4x

2

Non, it is a non-deduced context.

Non-deduced contexts.

In the following cases, the types, templates, and non-type values that are used to compose P do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.

<...>

4) A template parameter used in the parameter type of a function parameter that has a default argument that is being used in the call for which argument deduction is being done

+0

Vous parlez de la déduction d'argument de modèle. L'OP demande une déduction pour 'auto'. –

+0

@R Sahu comment la déduction de type pour le paramètre "auto" (défini dans les mini-concepts TS) diffère-t-elle de celle pour les paramètres du template? –

+0

Les types 'auto' pour les paramètres de fonction ne sont pas pris en charge dans C++ 11. Il est uniquement pris en charge pour les fonctions lambda en C++ 14. Il y a une proposition pour le supporter en C++ 17. Je n'ai pas vu cette proposition. Je ne peux pas dire à quel point c'est similaire pour la déduction d'argument de modèle. ce n'est pas quelque chose que nous pouvons même discuter de manière significative avec C++ 11 ou C++ 14. –