我有一个包含各种算法的类:
class Algorithm{
Algorithm()=delete;
public:
template <typename IntegerType>
static IntegerType One(IntegerType a, IntegerType b);
template <typename IntegerType>
static IntegerType Two(IntegerType a, IntegerType b);
template <typename IntegerType>
static IntegerType Three(IntegerType a, IntegerType b);
// ...
};
可以通过以下方式调用它们:
int main(){
Algorithm::One(35,68);
Algorithm::Two(2344,65);
//...
}
现在我想创建一个函数,该函数将采用任何“算法”函数,并在调用该函数之前和之后执行相同的步骤。
这就是我所拥有的:
template <typename IntegerType>
void Run_Algorithm(std::function<IntegerType(IntegerType,IntegerType)>fun, IntegerType a, IntegerType b){
//... stuff ...
fun(a,b);
//... stuff ...
return;
}
当我尝试这样调用函数时:
Run_Algorithm(Algorithm::One,1,1);
我得到的错误是:
cannot resolve overloaded function ‘One’ based on conversion to type ‘std::function<int(int, int)>’
如何设置通用例程,将所需算法作为参数?
修改
This solution按预期工作。
它看起来像这样:
template <typename IntegerType>
void Run_Algorithm(IntegerType(*fun)(IntegerType, IntegerType), IntegerType a, IntegerType b){
//... stuff ...
fun(a,b);
//... stuff ...
return;
}
答案 0 :(得分:5)
函数模板的名称(如Algorithm::One
)在此处被视为一组重载函数的名称。要从该集合中选择一个重载,您需要将该名称放在需要特定函数类型(签名)的上下文中。使用std::function
是不可能的,因为它可以在其ctor中使用任何参数(具有一些“可调用”的要求)。
此外,使用std::function
作为参数类型不是必需的,如果函数是模板,则无用。它只会添加一个不必要的类型擦除和一个间接级别。传递函数的标准习语是:
template <typename Fun, typename IntegerType>
void Run_Algorithm(Fun fun, IntegerType a, IntegerType b);
但这并没有帮助您选择一个重载集的重载。您可以选择呼叫站点的重载,Dieter Lücking suggested,然后使用此惯用语。
但是,您可以提供过载/或者:
template < typename IntegerType >
void Run_Algorithm(IntegerType(*)(IntegerType, IntegerType),
IntegerType, IntegerType);
如果可能的话,它更专业,因此更受欢迎。这里,函数类型是严格IntegerType(IntegerType, IntegerType)
,因此编译器可以选择重载集的重载(来自名称Algorithm::One
)。
注意:根据[temp.deduct.type] / 5,IntegerType
位于参数{{1}的非推导上下文中的第一个参数中}。因此,第二个和第三个参数用于推导Algorithm::One
。扣除后,完全指定了函数类型,并可以选择重载。
问题仍然存在1)如果这是你想要的,2)如果有更好的方法去做你想做的事。
答案 1 :(得分:2)
你需要算法::一个&lt; int&gt; (不是算法::一个)并感谢ymett(Why can't my C++ compiler deduce template argument for boost function?):
template <class T> struct identity { typedef T type; };
template <typename IntegerType>
void Run_Algorithm(
typename identity<
std::function<IntegerType(IntegerType,IntegerType)>>::type fun,
IntegerType a,
IntegerType b)
{
}
int main() {
Run_Algorithm(Algorithm::One<int>,1,1);
return 0;
}
答案 2 :(得分:0)
你想要这样的东西:
template <template <typename T> class IntegerType>
void Run_Algorithm // ...