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

发布于 2024-09-05 17:27:51 字数 326 浏览 4 评论 0 原文

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

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);

但是还有更好的想法吗?

I think everyone has experience working with a code like the following:

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

Of course that won't compile, because it's not clear which function to be passed. And what's your commonly-used solution to the problem?

I know this will work:

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

But any better ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

等风来 2024-09-12 17:27:51

一种解决方案是使用模板函数:

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

One solution is to use template function:

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

The better way is to use functor with template operator():

struct fun
{
  template<typename T>
  void operator()(T&) const;
};
...
for_each(vec.begin(), vec.end(), fun()); // T for operator() will be deduced automatically
旧情勿念 2024-09-12 17:27:51

我想赞同基里尔的回答。如果 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);

——尽管与原始代码相比并没有很大的改进。正如您所看到的,您还必须显式指定第一个模板参数。

I'd like to second Kirill's answer. If fun() functions are implemented very similarly (same code involving different types), it's a good idea to rewrite them as one single template function. As an additional plus, you would get a possibility to elegantly specify the function you need.

It's usually recommended to use the C++ equivalent to the C-style type cast:

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

Even more appropriate is to use static_cast in this case:

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

since we want to hint the compiler to the proper type.

Although much more verbose, it's better simply for code maintenance reasons -- it's easier to search for such constructs in the code than for C-style type casts.

There is also a possibility to avoid using type casts in favor of an explicit template argument specification:

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

-- although it's not very big improvement from the original code. As you can see, you have to explicitly specify the first template parameter as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文