2010-12-09 2 views
3

Для образовательных целей я пытаюсь написать свою собственную функцию «ForEach»:Передача указателя на функцию в качестве параметра шаблона

#include <iostream> 
#include <string> 
#include <vector> 


// 
// This works 
// 
template<class Container> 
void ForEach_v1(const Container & inContainer, void (*Functor)(const std::string &)) 
{ 
    typename Container::const_iterator it = inContainer.begin(), end = inContainer.end(); 
    for (; it != end; ++it) 
    { 
     Functor(*it); 
    } 
} 


// 
// Does not work 
// 
template<class Container, class Functor> 
void ForEach_v2(const Container & inContainer, Functor inFunctor) 
{ 
    typename Container::const_iterator it = inContainer.begin(), end = inContainer.end(); 
    for (; it != end; ++it) 
    { 
     Functor(*it); 
    } 
} 

void PrintWord(const std::string & inMessage) 
{ 
    std::cout << inMessage << std::endl; 
} 

int main() 
{ 
    std::vector<std::string> words; 
    words.push_back("one"); 
    words.push_back("two"); 
    words.push_back("three"); 

    // Works fine. 
    std::cout << "v1" << std::endl; 
    ForEach_v1(words, PrintWord); 

    // Doesn't work. 
    std::cout << "v2" << std::endl; 
    ForEach_v2(words, PrintWord); 

    return 0; 
} 

Выходной сигнал составитель:

|| g++ -Wall -o test main.cpp 
|| main.cpp: In function 'void ForEach_v2(const Container&, Functor) [with Container = std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, Functor = void (*)(const std::string&)]': 
main.cpp|116| instantiated from here 
main.cpp|96| warning: unused variable 'it' 

выхода программы:

v1 
one 
two 
three 
v2 

Мои вопросы:

  • Почему нет ForEach_v2 распечатать что-нибудь?
  • Почему компилятор печатает «неиспользованную переменную» -warning для ForEach_v2?

ответ

8

Вы хотите

inFunctor(*it); 

не

Functor(*it); 
+1

Embarrassing ... – StackedCrooked 2010-12-09 19:54:56

3
template<class Container, class Functor> 
void ForEach_v2(const Container & inContainer, Functor inFunctor) 
{ 
    typename Container::const_iterator it = inContainer.begin(), end = inContainer.end(); 
    for (; it != end; ++it) 
    { 
     Functor(*it); 
    } 
} 

должны быть

template<class Container, class Functor> 
void ForEach_v2(const Container & inContainer, Functor inFunctor) 
{ 
    typename Container::const_iterator it = inContainer.begin(), end = inContainer.end(); 
    for (; it != end; ++it) 
    { 
     inFunctor(*it); 
    } 
} 
2

Вот ваша проблема:

for (; it != end; ++it) 
    { 
     Functor(*it); 
    } 

Functor в настоящее время является типа функции вы прошли.

Вам нужно написать следующее:

for (; it != end; ++it) 
    { 
     inFunctor(*it); //note this change! 
    } 

Теперь это будет работать!

Смежные вопросы