如何使用重载函数作为函数模板的参数?

时间:2010-06-14 06:20:00

标签: c++ templates overloading

我认为每个人都有使用以下代码的经验:

void fun(Type1&);
void fun(Type2&);
vector<Type1> vec;
for_each(vec.begin(), vec.end(), fun);

当然不会编译,因为不清楚要传递哪个函数。你常用的解决方案是什么?

我知道这会奏效:

for_each(vec.begin(), vec.end(), (void(*)(Type1&))fun);

但是还有更好的想法吗?

2 个答案:

答案 0 :(得分:2)

一种解决方案是使用模板功能:

template<typename T>
void fun(T&);
// specialize fun for Type1 and Type2
...
for_each(vec.begin(), vec.end(), fun<Type1>);

更好的方法是使用带有模板operator()的仿函数:

struct fun
{
  template<typename T>
  void operator()(T&) const;
};
...
for_each(vec.begin(), vec.end(), fun()); // T for operator() will be deduced automatically

答案 1 :(得分:0)

我想回答基里尔的回答。如果fun()函数的实现非常相似(相同的代码涉及不同的类型),最好将它们重写为单个模板函数。另外,您可以优雅地指定所需的功能。

通常建议使用与C风格类型转换相当的C ++:

for_each(vec.begin(), vec.end(), reinterpret_cast<void(*)(Type1&)>(fun));

更合适的是在这种情况下使用static_cast:

for_each(vec.begin(), vec.end(), static_cast<void(*)(Type1&)>(fun));

因为我们想要将编译器提示为正确的类型。

虽然更加冗长,但仅仅出于代码维护的原因更好 - 在代码中搜索这样的结构比在C风格的类型转换中更容易。

还有可能避免使用类型转换来支持显式模板参数规范:

for_each<std::vector<A>::iterator, void(*)(Type1&)>(vec.begin(), vec.end(), fun);

- 虽然它与原始代码相比没有太大的改进。如您所见,您还必须明确指定第一个模板参数。