3
struct A // some class
{
  void method(); // non-static member method
  static void function(); // static member method
};
void function(); // global function
vector<A> vi; // any such `std` like container

我想要一个Iterate()可以通过以下方式调用的函数(比如):

Iterate(vi, &A::method);  // (1)
Iterate(vi, &A::function); // (2a)
Iterate(vi, &function); // (2b)

(2a) 和 (2b) 完全相同。

现在Iterate()原型如下(1)和(2):

template<typename Container, typename Method>
void Iterate (Container &container, Method method); // for (1)

template<typename Container, typename Function>
void Iterate (Container &container, Function function); // for (2a), (2b)

自然两者完全相同,这会导致编译器错误。
有没有办法Iterate()在 C++03 中重载/专门化,这将允许两个函数共存?

4

1 回答 1

1

您可以使一个功能比另一个功能更具体:

template<typename Container, typename Functor>
void Iterate (Container &container, Functor fun); 

template<typename Container, typename R, typename ..Args>
void Iterate (Container &container, R (Container::value_type::*fun)(Args...));

第一个模板适用于常规函数、函数对象和静态成员函数,而第二个模板仅适用于非静态成员函数。

在 C++03 中,您可以通过编写重载来模拟可变参数模板,如下所示:

template<typename Container, typename R>
void Iterate (Container &container, R (Container::value_type::*fun)());

template<typename Container, typename R, typename Arg>
void Iterate (Container &container, R (Container::value_type::*fun)(Arg));

template<typename Container, typename R, typename Arg1, typename Arg2>
void Iterate (Container &container, R (Container::value_type::*fun)(Arg1, Arg2));

//add more overloads to handle member functions 
//that take 3 or more arguments

当然,如果您必须以不同的方式实现它们。例如,调用成员函数(obj.*fun)(a1,a2,a3);的语法是,而仿函数调用语法是 just fun(a1,a2,a2)。我不知道您会将哪些参数传递给函数(成员或仿函数)。我假设这不是真正的代码,您只是想探索语法。

重要的一点是,调用函子不需要(从容器中),但您可以将其作为参数传递给obj

于 2012-12-29T15:03:19.693 回答