185 votes

Arguments de modèle par défaut pour les modèles de fonction

Pourquoi les arguments de modèle par défaut ne sont-ils autorisés que sur les modèles de classe? Pourquoi ne pouvons-nous pas définir un type par défaut dans un modèle de fonction membre? Par exemple:

 struct mycclass {
  template<class T=int>
  void mymember(T* vec) {
    // ...
  }
};
 

Au lieu de cela, C ++ force les arguments de modèle par défaut à être autorisés uniquement sur un modèle de classe.

147voto

Johannes Schaub - litb Points 256113

Il est logique de donner le modèle par défaut arguments. Par exemple, vous pouvez créer une fonction de tri:

template<typename Iterator, typename Comp = std::less<Iterator> >
void sort(Iterator beg, Iterator end, Comp c = Comp()) {
  ...
}

C++0x une introduction à C++. Voir ce rapport de défaut par Bjarne Stroustrup: Modèle par Défaut Arguments pour les Modèles de Fonction et ce qu'il dit

L'interdiction de modèle par défaut arguments pour les modèles de fonction est un bâtard vestige de l'époque où autonome des fonctions ont été traités comme des citoyens de seconde classe et nécessaire de tous les arguments de modèle à être déduites à partir des arguments de la fonction plutôt que spécifique.

La restriction au sérieux des crampes le style de programmation par inutilement de décision autonome des fonctions différentes à partir des fonctions de membre du, rendant d'autant plus difficile à écrire STL-code de style.

35voto

James McNellis Points 193607

Pour citer modèles C++ : The Complete Guide (page 207) :

Lorsque les modèles étaient initialement inscrits sur le langage C++, arguments de modèle de fonction explicite n’étaient pas une construction valide. Arguments de modèle de fonction devaient toujours être déduites de l’expression d’appel. Ainsi, il semble y avoir aucune raison impérieuse pour permettre des arguments template fonction par défaut car la valeur par défaut serait toujours être substituée par la valeur déduite.

17voto

Steve Jessop Points 166970

Jusqu'à présent, tous les proféré des exemples de modèle par défaut des paramètres pour les modèles de fonction peut être fait avec les surcharges.

AraK:

struct S { 
    template <class R = int> R get_me_R() { return R(); } 
};

pourrait être:

struct S {
    template <class R> R get_me_R() { return R(); } 
    int get_me_R() { return int(); }
};

Mon propre:

template <int N = 1> int &increment(int &i) { i += N; return i; }

pourrait être:

template <int N> int &increment(int &i) { i += N; return i; }
int &increment(int &i) { return increment<1>(i); }

litb:

template<typename Iterator, typename Comp = std::less<Iterator> >
void sort(Iterator beg, Iterator end, Comp c = Comp())

pourrait être:

template<typename Iterator>
void sort(Iterator beg, Iterator end, std::less<Iterator> c = std::less<Iterator>())

template<typename Iterator, typename Comp >
void sort(Iterator beg, Iterator end, Comp c = Comp())

Stroustrup:

template <class T, class U = double>
void f(T t = 0, U u = 0);

Pourrait être:

template <typename S, typename T> void f(S s = 0, T t = 0);
template <typename S> void f(S s = 0, double t = 0);

Qui j'ai prouvé avec le code suivant:

#include <iostream>
#include <string>
#include <sstream>
#include <ctype.h>

template <typename T> T prettify(T t) { return t; }
std::string prettify(char c) { 
    std::stringstream ss;
    if (isprint((unsigned char)c)) {
        ss << "'" << c << "'";
    } else {
        ss << (int)c;
    }
    return ss.str();
}

template <typename S, typename T> void g(S s, T t){
    std::cout << "f<" << typeid(S).name() << "," << typeid(T).name()
        << ">(" << s << "," << prettify(t) << ")\n";
}


template <typename S, typename T> void f(S s = 0, T t = 0){
    g<S,T>(s,t);
}

template <typename S> void f(S s = 0, double t = 0) {
    g<S,double>(s, t);
}

int main() {
        f(1, 'c');         // f<int,char>(1,'c')
        f(1);              // f<int,double>(1,0)
//        f();               // error: T cannot be deduced
        f<int>();          // f<int,double>(0,0)
        f<int,char>();     // f<int,char>(0,0)
}

La sortie imprimée correspond à des observations pour chaque appel à f, et le commentée d'échec de l'appel à compiler comme prévu.

Donc je pense que par défaut les paramètres de modèle "ne sont pas nécessaires", mais probablement seulement dans le même sens que la valeur par défaut des arguments de la fonction "ne sont pas nécessaires". Comme de Stroustrup rapport de défaut indique, l'ajout de la non-déduire des paramètres était trop tard pour quiconque de réaliser et/ou apprécie vraiment qu'il fait par défaut utiles. Donc, la situation actuelle est en effet basée sur une version de modèles de fonction qui n'a jamais été la norme.

4voto

Adi Shavit Points 4470

Sous Windows, avec toutes les versions de Visual Studio vous pouvez convertir cette erreur (C4519 sous) pour une mise en garde ou désactivez-le comme suit :

Voir plus de détails ici.

1voto

alariq Points 160

Ce que j’utilise est le prochain tour ;

permet de dire, vous voulez avoir la fonction comme ceci

vous ne serez pas autorisé, mais je le fais moyen suivant :

Si cette façon vous pouvez l’utiliser comme ça.

comme nous ne pouvons voir aucun besoin de définir explicitement le second paramètre. il sera peut-être utile pour quelqu'un.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X