1

我有一个包含各种算法的类:

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

我该如何设置一个通用例程,它将所需的算法作为参数?

编辑:
此解决方案按需要工作。它看起来像这样:

template <typename IntegerType>
void Run_Algorithm(IntegerType(*fun)(IntegerType, IntegerType), IntegerType a, IntegerType b){
    //... stuff ...
    fun(a,b);
    //... stuff ...
    return;
}
4

3 回答 3

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 的 建议在呼叫现场选择重载,然后使用此成语。

但是,您可以提供重载/或者:

template < typename IntegerType >
void Run_Algorithm(IntegerType(*)(IntegerType, IntegerType),
                   IntegerType, IntegerType);

如果可能的话,它更专业,因此更受欢迎。这里,函数类型是 strict IntegerType(IntegerType, IntegerType),因此编译器可以选择重载集的重载(从 name Algorithm::One)。

注意:根据 [temp.deduct.type]/5,IntegerType在参数的非推导上下文中的第一个参数中Algorithm::One。因此,使用第二个和第三个参数来推导IntegerType。如此推演后,函数类型完全指定,可以选择重载。

问题仍然存在:1)如果那是你想要的,2)是否有更好的方法来做你想做的事情。

于 2013-09-08T14:16:53.147 回答
2

您需要 Algorithm::One< int > (不是 Algorithm::One)并且感谢 ymett (为什么我的 C++ 编译器不能推断出 boost 函数的模板参数?):

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;
}
于 2013-09-08T14:17:09.803 回答
0

你想要这样的东西:

template <template <typename T> class IntegerType>
void Run_Algorithm // ...
于 2013-09-08T13:57:57.007 回答