2017-07-13 2 views
2

Je veux écrire un modèle variadique ou des expressions const qui 1) exécute un modèle de foncteur N fois et 2) accumule le résultat. J'ai écrit un petit exemple qui échoue la compilation dès que je déplace la fonction qui est exécutée dans un foncteur de modèle. J'ai l'impression d'être proche de la solution, mais peut-être que je me trompe.Modèle variadique simple (récursif) Fonction "accumulate_for" avec problèmes de compilation

#include <iostream> 
#include <string> 

struct F { 
    template <int id> 
    static int run(int val) { 
     return id * val; 
    } 
}; 

template<unsigned int n> 
struct accumulate_for 
{ 
    template <class Funct> 
    static int get(int val) { 
     return 
     (
     accumulate_for<n-1>::get(val) 
     + 
     Funct::run<n>(val) 
     ); 
    } 
}; 

template<> 
struct accumulate_for<0> 
{ 
    template <class Funct> 
    static int get(int val) { 
     return 0; 
    } 
}; 

int main() 
{ 
    std::cout << accumulate_for<3>::get<F>(1) << std::endl; 
} 
+0

[alternatif avec std :: index_sequence] (http://coliru.stacked-crooked.com/ a/a9946dfd1a8890ef) – Jarod42

Répondre

5
  1. accumulate_for<n>::get est un modèle de fonction de membre, vous devez spécifier un argument de modèle lors de l'appel. Vous devez utiliser template keyword pour indiquer que get et run (qui sont les deux noms dépendants) sont des modèles.

par exemple.

template<unsigned int n> 
struct accumulate_for 
{ 
    template <class Funct> 
    static int get(int val) { 
     return 
     (
     accumulate_for<n-1>::template get<Funct>(val) 
     //     ~~~~~~~~ ~~~~~~~ 
     + 
     Funct::template run<n>(val) 
     //  ~~~~~~~~ 
     ); 
    } 
}; 

LIVE

Pour plus d'informations sur l'utilisation du mot-clé template, reportez-vous à Where and why do I have to put the “template” and “typename” keywords?

+0

Je ne comprends pas pourquoi le mot-clé template est nécessaire. Le compilateur devrait voir ça ?! – dgrat

+1

@dgrat Avez-vous vérifié le lien? En résumé, sans cela, pour 'get ', le compilateur ne considérera pas 'get' comme un nom de modèle, alors' <'sera analysé comme le signe inférieur. D'un autre côté, il pourrait y avoir des spécificités de 'accumulate_for' (par exemple' accumulate_for <99> '?), Qui a un membre de données statique nommé' get', puis rend 'accumulate_for :: get songyuanyao