2012-02-16 2 views
3

Пусть у меня есть функция, которая делает что-то на любом типе контейнера (C++ 11):Pass шаблон функции для другой функции

template<class containerType> 
void bar(containerType& vec) { 

     for (auto i: vec) { 
       std::cout << i << ", "; 
     } 

     std::cout << '\n'; 
} 

Я могу назвать эту функцию из другой функции, как это:

void foo() { 
     std::vector<int> vec = { 1, 2, 3 }; 
     bar(vec); 
} 

Теперь предположим, что у меня есть различные функции, так же, как бар, и я хочу передать одну из этих функций в Foo, то Foo будет выглядеть примерно так:

template<class funcType> 
void foo(funcType func) { 
    std::vector<int> vec = { 1, 2, 3 }; 
    func(vec); 
} 

Однако, называя Foo так:

foo(bar); 

не работает (довольно ясно, так как бар не функция, а шаблон функции). Есть ли хорошее решение для этого? Как я должен определить foo, чтобы сделать эту работу?

EDIT: здесь минимальный compileable пример, как потребовано в комментариях ...

#include <iostream> 
#include <vector> 
#include <list> 

template<class containerType> 
void bar(containerType& vec) { 

     for (auto i: vec) { 
       std::cout << i << ", "; 
     } 

     std::cout << '\n'; 
} 

template<typename funcType> 
void foo(funcType func) { 

     std::vector<int> vals = { 1, 2, 3 }; 
     func(vals); 

} 

int main() { 
     // foo(bar); - does not work. 
} 
+0

у вас отсутствует минимальный компилируемый пример –

+1

Почему вы используете указатели функций использования? Я считаю, что использование функтора было бы лучше здесь. – AlexTheo

+0

@AlexTheo Спасибо за ваш комментарий. Конечно, используя функторы, решение простое! Боб опубликовал аналогичное решение в качестве ответа. Я пойду с этим! – fdlm

ответ

2

Что-то вроде этого? (Не полностью проснулся, может пропустить точку)

#include <iostream> 
#include <vector> 
#include <list> 

struct Test{ 
template<class containerType> 
static void apply(containerType& vec) { 

     for (auto it = vec.begin(); it != vec.end(); ++it) { 
       std::cout << *it << ", "; 
     } 

     std::cout << '\n'; 
} 
}; 

template<class FuncStruct> 
void foo() { 

     std::vector<int> vals; 
     vals.push_back(1); 
     FuncStruct::apply(vals); 

} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    foo<Test>(); 
    return 0; 
} 
+0

Спасибо! Точно так же, как @AlexTheo указал в комментариях, использование функтора, вероятно, является самым простым решением здесь. – fdlm

3

Если вы знаете, что Foo работает с вектором Int, вы можете передать bar< std::vector<int> > функцию.

Разумным решением будет модуль, который определяет foo, чтобы также определить typedef для используемого контейнера. Тогда вам даже не понадобится bar.

+0

Спасибо за ваш ответ. Я бы предпочел, чтобы вызывающий foo не знал, как работает foo внутри - он просто знает, что ему нужно передать функцию, которая работает с произвольными контейнерами. – fdlm

+0

@fldm: См. Редактирование. –

+1

@fdlm, но функция не работает на произвольных контейнерах. Это функция шаблона, поэтому подумайте об этом как о создании функции для требуемого типа контейнера во время компиляции. – juanchopanza

4

Интернет демо на http://ideone.com/HEIAl

Это позволяет сделать foo(bar). Вместо того, чтобы проходить в шаблоне-функции или в классе-шаблоне, мы передаем класс без шаблона, который имеет функцию-член-шаблон.

#include <iostream> 
#include <vector> 
#include <list> 

struct { 
    template<class containerType> 
    void operator() (containerType& vec) { 

     for (auto i = vec.begin(); i!=vec.end(); ++i) { 
       std::cout << *i << ", "; 
     } 

     std::cout << '\n'; 

    } 
} bar; 

template<typename funcType> 
void foo(funcType func) { 

     std::vector<int> vals = { 1, 2, 3 }; 
     func(vals); 

} 

int main() { 
     foo(bar); 
} 
Смежные вопросы