2015-04-23 1 views
2

Quelqu'un pourrait m'aider à implémenter ce code?Transmettre une méthode de modèle comme argument

J'ai besoin de passer d'une fonction à une autre fonction:

std::cout << process_time(Model::method1) << std::endl; 

Cette fonction obtient la fonction comme un type de modèle et il appelle un objet

template <typename F> 
double process_time(F algorithm) 
{ 
    Model model; 
    double time=0; 
    do 
    { 
     // ... 
     time += model.algorithm(arg1); 
    } while (! stop_criteria); 
    return time; 
} 

Notez que method1 est un modèle de fonction ainsi:

template <typename T> 
double method1(std::vector<T> &v) 
{ 
    ... 
} 

Quelle est la syntaxe légale pour cela?

main.cpp

#include <iostream> 
#include <vector> 

class Model 
{ 
public: 

    template <typename T> 
    double method1(std::vector<T> &v) 
    { 
     double t = 0; 
     //... 
     return t; 
    } 

    template <typename T> 
    double method2(std::vector<T> &v) 
    { 
     double t = 0; 
     //... 
     return t; 
    } 

}; 

template <typename F> 
double process_time(F algorithm) 
{ 
    Model model; 
    double time = 0; 
    bool stop_criteria = false; 
    do 
    { 
     std::vector<int> arg1; 
     // ... 
     time += model.algorithm(arg1); 
    } while (!stop_criteria); 
    return time; 
} 

int main() 
{ 
    std::cout << process_time(Model::method1) << std::endl; 
    return 0; 
} 
+2

Qu'est-ce que 'method1'? Qu'est-ce que vous essayez de faire? Pouvez-vous fournir un [MCVE] (http://www.stackoverflow.com/help/mcve) – Barry

+0

Qu'est-ce que 'process_time'? – anxieux

+0

@anxieux désolé, corrigé – zahmati

Répondre

1

Ceci est le plus proche de votre code qui compile:

#include <iostream> 
#include <vector> 

struct Model { 
    template <typename T> 
    double method1(std::vector<T> &v) { 
    double t = 0; 
    //... 
    return t; 
    } 
}; 

template <typename F> 
double process_time(F algorithm) { 
    Model model; 
    double time = 0; 
    bool stop_criteria = false; 
    do 
    { 
     std::vector<int> arg1; 
     // ... 
     time += (model.*algorithm)(arg1); 
    } while (!stop_criteria); 
    return time; 
} 

int main() { 
    std::cout << process_time(&Model::method1<int>) << std::endl; 
} 
2

La clé est que method1 est une fonction modèle:

template <typename T> double method1(std::vector<T>&); 

En tant que tel, ce n'est pas fonction ... c'est une famille de fonctions . process_time attend une seule fonction, il vous suffit de passer la fonction un que vous souhaitez utiliser:

std::cout << process_time(method1<int>) << std::endl; 
1

Changer votre process time ligne avec time += à:

time += algorithm(&model,arg1); 

puis appelez avec:

std::cout << process_time([](Model* m, std::vector<int>& v){return m->method1(v);}) << std::endl; 

ou en C++ 14:

std::cout << process_time([](Model* m, auto& v){return m->method1(v);}) << std::endl; 

qui laisse le choix de ce type de vecteur, il passera à method1 jusqu'à process_time au lieu de le fixer sur le site d'appel. Fondamentalement, cela évite de gérer les variables pointeur vers membre. Au lieu de cela, le algorithm en process_time est juste une carte de Model x vector à double. Cela signifie également que nous pouvons avoir un non-membre algorithm.

Si vous ne l'aimez pas la verbosité de ce qui précède sur le site d'appel, vous pouvez conserver les modifications à process_time et changer l'appel à:

std::cout << process_time(std::ref(&Model::method1<int>)) << std::endl; 

comme std::ref prend un pointeur vers une fonction membre, et retourne un objet appelable qui prend un pointeur sur Model comme premier argument, et std::vector<int>& comme second argument. Ce qui correspond à la façon dont nous l'utilisons.