初学者模板编译错误 - 无法将函数作为arg传递

时间:2010-10-30 12:06:52

标签: c++ class templates compiler-errors

我的大多数课程都将列表作为私人数据成员。因此,他们中的大多数也有加法器/卸妆公众成员。我注意到我为每个加法器写了基本相同的东西,所以我想我会把它变成一个模板。

这就是我所拥有的:

template <class N, class I>
void add(N element, std::list<N> & container, I (*f)(void),
  std::string successmsg, std::string exceptmsg) {
 typename std::list<N>::iterator it;

 it = find(container.begin(), container.end(), element);
 try {
  if(it != container.end())
   throw DuplicateElement<I>(element->(*f));
 }
 catch (DuplicateElement<I>&){
  std::cout << exceptmsg;
  pause(PAUSE_MESSAGE);
  return;
 }
 container.push_back(element);
 std::cout << successmsg;
}

让我解释一下,它的参数(按顺序)是要添加的元素,元素应添加到的容器,元素类上的函数返回其唯一ID(代码,许可证)盘子,无论如何),成功消息和异常消息。

样本用法:

void Aeroporto::addCompanhia(CompanhiaAerea* companhia) {

 std::string success = "Companhia aérea adicionada com sucesso!";
 std::string except = "Companhia aérea já existente!";
 add(companhia, companhias, getSigla, success, except);
// std::list<CompanhiaAerea*>::iterator it;
//
//  it = find(companhias.begin(), companhias.end(), companhia);
//  try{
//   if(it != companhias.end())
//    throw DuplicateElement<std::string>(companhia->getSigla());
//  }
//  catch (DuplicateElement<std::string>&){
//     std::cout << "Companhia aérea já existente!";
//     pause(PAUSE_MESSAGE);
//     return;
//  }
//
//  companhias.push_back(companhia);
//  std::cout << "Companhia aérea adicionada com sucesso!";

}

当我尝试编译时,我得到以下内容:

..\src\/headers/template.h: In function 'void add(N, std::list<N>&, I (*)(), std::string, std::string)':
..\src\/headers/template.h:23:29: error: expected primary-expression before '(' token
..\src\/headers/template.h:23:39: error: expected unqualified-id before '(' token
..\src\aeroporto.cpp: In member function 'void Aeroporto::addCompanhia(CompanhiaAerea*)':
..\src\aeroporto.cpp:76:54: error: no matching function for call to 'add(CompanhiaAerea*&, std::list<CompanhiaAerea*>&, <unresolved overloaded function type>, std::string&, std::string&)'

我需要你的帮助,因为谷歌这种东西并不是特别容易。

感谢您的时间!

2 个答案:

答案 0 :(得分:3)

因为你想使用一个方法,你必须使用指向成员的指针函数:

template <class N, class I>
void add(N* element, std::list<N*>& container, I (N::*f)() const,
  std::string successmsg, std::string exceptmsg) {
 typename std::list<N*>::iterator it;

 it = find(container.begin(), container.end(), element);
 try {
  if(it != container.end())
   throw DuplicateElement<I>((element->*f)());
//...
//...
add(companhia, companhias, &CompanhiaAerea::getSigla, success, except);
//...

请注意我必须如何更改N的使用方式,才能获得f的正确类型。

答案 1 :(得分:2)

您不想传递函数指针,而是传递成员函数指针。它们在C ++中完全不同(基本上是隐式this参数)。这是一个关于如何传递自由函数,静态成员函数和非静态成员函数的简单测试用例。您必须使用模板部分完成它:

struct test {
   void foo() { std::cout << "test::foo" << std::endl; }
   static void bar() { std::cout << "test::bar" << std::endl; }
};
void foo() { std::cout << "foo" << std::endl; }

void call_function( void (*f)() )
{
   f();
}
void call_member( test & t, void (test::*f)() )
{
   t.*f();
   (&t)->*f();
}
int main() 
{
   test t;
   call_function( &foo );        // free function
   call_function( &test::bar );  // equivalent for static member function
   call_member( t, &test::foo ); // but not for member function
}