我的代码的简化版本在这里
int foo(int x)
{
return x;
}
int foo(int x, int y)
{
return x+y;
}
template<typename unary_func>
int bar(int k, unary_func f)
{
return f(k);
}
int main()
{
bar(3, foo);
return 0;
}
有没有办法告诉编译器我要传递什么,因为参数是第一个`foo'?
答案 0 :(得分:10)
您可以提供明确的模板参数:
bar<int(int)>(3, foo);
或将不明确的函数名称转换为可以推导出模板参数的类型:
bar(3, static_cast<int(*)(int)>(foo));
或将其包装在另一个函数(或函数对象)中以消除歧义
bar(3, [](int x){return foo(x);});
答案 1 :(得分:3)
我使用以下宏处理此问题:
#define LIFT(fname) \
[] (auto&&... args) -> decltype (auto) \
{ \
return fname (std::forward <decltype (args)> (args)...); \
}
根据您对foo
和bar
的定义,您可以说
int main()
{
bar(3, LIFT(foo));
return 0;
}
将选择正确的过载。这使用了C ++ 14的一些功能,即通用lambdas和decltype(auto)
。如果你正在使用C ++ 11,你可以通过更多的工作获得或多或少相同的效果:
#define DECLARE_LIFTABLE(NAME) \
struct NAME##_lifter \
{ \
template <typename... Args> \
auto operator () (Args&&... args) -> decltype (NAME (std::forward <Args> (args)...)) \
{ \
return NAME (std::forward <decltype (args)> (args)...); \
} \
}
#define LIFT(NAME) (NAME##_lifter {})
DECLARE_LIFTABLE(foo);
int main()
{
bar(3, LIFT(foo));
return 0;
}
如果您正在使用C ++ 98,那么您基本上会使用强制转换为适当的函数指针类型。
答案 2 :(得分:2)
不,你不能,因为你只用一个参数调用函数,你需要一个只有一个参数的类型。相反,您可以按值使用模板(无类型名称或类)
一个论点:
int foo(int x)
{
return x;
}
int foo(int x, int y)
{
return x+y;
}
typedef int (*foo_fcn)(int);
template<foo_fcn unary_func>
int bar(int k)
{
return unary_func(k);
}
int main()
{
bar<foo>(3);
return 0;
}
两个论点:
int foo(int x)
{
return x;
}
int foo(int x, int y)
{
return x+y;
}
typedef int (*foo_fcn)(int, int);
template<foo_fcn unary_func>
int bar(int k)
{
return unary_func(k, k);
}
int main()
{
bar<foo>(3);
return 0;
}
这两种:
int foo(int x) // first foo
{
return x;
}
int foo(int x, int y) // second foo
{
return x+y;
}
typedef int (*foo_fcn)(int);
typedef int (*foo_fcn_2)(int, int);
template<foo_fcn unary_func>
int bar(int k)
{
return unary_func(k);
}
template<foo_fcn_2 unary_func>
int bar(int a, int b)
{
return unary_func(a, b);
}
int main()
{
bar<foo>(3,1); // compiler will choose first foo
bar<foo>(4); // compiler will choose second foo
return 0;
}
答案 3 :(得分:1)
是:
bar(3, static_cast<int(*)(int)>(&foo));
或:
bar<int(*)(int)>(3, &foo);