如何指定指向重载函数的指针?
我想将重载函数传递给 std::for_each()
算法。例如,
class A {
void f(char c);
void f(int i);
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), f);
}
};
我希望编译器通过迭代器类型解析 f()
。显然,它(GCC 4.1.2)没有这样做。那么,我如何指定我想要的 f()
呢?
I want to pass an overloaded function to the std::for_each()
algorithm. For example,
class A {
void f(char c);
void f(int i);
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), f);
}
};
I'd expect the compiler to resolve f()
by the iterator type. Apparently, it (GCC 4.1.2) doesn't do it. So, how can I specify which f()
I want?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以使用
static_cast<>()
根据函数指针类型隐含的函数签名来指定要使用哪个f
:或者,您也可以这样做:
如果
f
是一个成员函数,那么你需要使用mem_fun
,或者根据您的情况,使用Dobb 博士的文章中介绍的解决方案< /a>.You can use
static_cast<>()
to specify whichf
to use according to the function signature implied by the function pointer type:Or, you can also do this:
If
f
is a member function, then you need to usemem_fun
, or for your case, use the solution presented in this Dr. Dobb's article.兰姆达来救援! (注意:需要 C++11)
或者使用 decltype 作为 lambda 参数:
使用多态 lambda (C++14):
或者通过删除重载来消除歧义(仅适用于自由函数):
Lambdas to the rescue! (note: C++11 required)
Or using decltype for the lambda parameter:
With polymorphic lambdas (C++14):
Or disambiguate by removing overloading (only works for free functions):
为什么不起作用
如果真是这样那就太好了!然而,
for_each
是一个函数模板,声明为:模板推导需要在调用时为
UnaryFunction
选择一个类型。但f
没有特定的类型 - 它是一个重载函数,有许多f
,每个都有不同的类型。for_each
目前没有办法通过说明它想要哪个f
来帮助模板推导过程,因此模板推导根本会失败。为了让模板推演成功,还需要在调用端做更多的工作。修复它的通用解决方案
几年后跳到这里,C++14 之后。而不是使用
static_cast
(这将允许模板推导通过“修复”我们想要使用的f
来成功,但需要您手动执行重载解析来“修复”正确的),我们想让编译器为我们工作。我们想要对某些参数调用f
。以最通用的方式可能,那就是:需要输入很多内容,但是这种问题经常出现,令人烦恼,所以我们可以将其包装在宏中(叹气):
然后使用它:
这将完全按照您的方式进行希望编译器这样做 - 对名称
f
本身执行重载解析并做正确的事情。无论f
是自由函数还是成员函数,这都会起作用。Why doesn't it work
It'd be great if that were the case! However,
for_each
is a function template, declared as:Template deduction needs to select a type for
UnaryFunction
at the point of the call. Butf
doesn't have a specific type - it's an overloaded function, there are manyf
s each with different types. There is no current way forfor_each
to aid the template deduction process by stating whichf
it wants, so template deduction simply fails. In order to have the template deduction succeed, you need to do more work on the call site.Generic solution to fixing it
Hopping in here a few years and C++14 later. Rather than use a
static_cast
(which would allow template deduction to succeed by "fixing" whichf
we want to use, but requires you to manually do overload resolution to "fix" the correct one), we want to make the compiler work for us. We want to callf
on some args. In the most generic way possible, that's:That's a lot to type, but this sort of problem comes up annoyingly frequently, so we can just wrap that in a macro (sigh):
and then just use it:
This will do exactly what you wish the compiler did - perform overload resolution on the name
f
itself and just do the right thing. This will work regardless of whetherf
is a free function or a member function.这里的问题似乎不是重载解析,而是模板参数推导。虽然 @In silico 的 优秀答案 一般会解决模糊的重载问题,但在处理 < 时,这似乎是最好的解决方法code>std::for_each (或类似)是显式指定其模板参数:
The problem here seems to be not overload resolution but in fact template parameter deduction. While the excellent answer from @In silico will solve an ambiguous overloading problem in general, it seems the best fix when dealing with
std::for_each
(or similar) is to explicitly specify its template parameters:如果您不介意使用 C++11,这里有一个聪明的助手,它类似于(但不那么难看)静态转换:(
适用于成员函数;应该很明显如何修改它以适用于独立函数,并且您应该能够提供这两个版本,编译器将为您选择正确的版本。)
感谢 Miro Knejp 的建议:另请参阅https://groups.google.com/a/isocpp.org/d/msg/std-discussion/ rLVGeGUXsK0/IGj9dKmSyx4J。
If you don't mind using C++11, here's a clever helper that is similar to (but less ugly than) the static cast:
(Works for member functions; should be obvious how to modify it to work for freestanding functions, and you should be able to provide both versions and the compiler will select the right one for you.)
With thanks to Miro Knejp for suggesting: see also https://groups.google.com/a/isocpp.org/d/msg/std-discussion/rLVGeGUXsK0/IGj9dKmSyx4J.
不是为了回答你的问题,但我是唯一一个发现
比计算机在这种情况下建议的
for_each
替代方案更简单和更短的人吗?Not to answer your question, but am I the only one that finds
both simpler and shorter than the
for_each
alternative suggested by in silico in this case?