【问题标题】:C++ function pointer to function that takes a template as an arguement指向以模板为参数的函数的 C++ 函数指针
【发布时间】:2014-04-14 21:20:38
【问题描述】:

如何将函数指针指向以模板作为参数的函数? 我正在尝试创建一个指向该函数的指针

template<typename BaseType>
int indexOfLargest(const BaseType list[], int startIndex, int endIndex) {
    if (startIndex < 0 || startIndex > endIndex)
        return -1;

    int indexOfMax = startIndex;
    for (int index = startIndex + 1; index < endIndex; index++)
        if (list[index] > list[indexOfMax])
            indexOfMax = index;
    return indexOfMax;
}

还有这个功能

template<typename BaseType>
int indexOfSmallest(const BaseType list[], int startIndex, int endIndex) {
    if (startIndex < 0 || startIndex > endIndex)
        return -1;

    int indexOfMin = startIndex;
    for (int index = startIndex + 1; index < endIndex; index++)
        if (list[index] < list[indexOfMin])
            indexOfMin = index;
    return indexOfMin;
}

所以我可以避免在每次迭代时执行 if 语句。

template<typename A0, typename A1, typename A2, typename A3, typename A4>
void sortArrayData(A0 a0[], A1 a1[], A2 a2[], A3 a3[], A4 a4[],
        const int recordCount, int order) {
    int indexOfNext;

    for (int index = 0; index < recordCount - 1; index++) {
        if (order == 1)
            indexOfNext = indexOfSmallest(a0, index, recordCount);
        else
            indexOfNext = indexOfLargest(a0, index, recordCount);

        swap_v(a0[index], a0[indexOfNext]);
        swap_v(a1[index], a1[indexOfNext]);
        swap_v(a2[index], a2[indexOfNext]);
        swap_v(a3[index], a3[indexOfNext]);
        swap_v(a4[index], a4[indexOfNext]);
    }

}

-- 另外,我在网上或其他程序员那里找不到任何答案。

谢谢

【问题讨论】:

    标签: c++ templates pointers function-pointers


    【解决方案1】:

    有几种方法。你可以让编译器帮你解决:

    template<typename A0, typename A1, typename A2, typename A3, typename A4, typename F>
    void sortArrayData(A0 a0[], 
                       A1 a1[], 
                       A2 a2[], 
                       A3 a3[], 
                       A4 a4[],
                       const int recordCount, 
                       F indexFunc)
    {
        int indexOfNext;
    
        for (int index = 0; index < recordCount - 1; index++) {
            indexOfNext = indexFunc(a0, index, recordCount);
            // ...
        }
    }
    

    或者您可以直接将签名指定为函数或 std::function。

    template<typename A0, typename A1, typename A2, typename A3, typename A4>
    void sortArrayData(A0 a0[], 
                       A1 a1[], 
                       A2 a2[], 
                       A3 a3[], 
                       A4 a4[],
                       const int recordCount, 
                       std::function<int (A0, int, int)> indexFunc)
    {
        int indexOfNext;
    
        for (int index = 0; index < recordCount - 1; index++) {
            indexOfNext = indexFunc(a0, index, recordCount);
            // ...
        }
    }
    

    你也可以为函数声明一个局部变量:

    template<typename A0, typename A1, typename A2, typename A3, typename A4>
    void sortArrayData(A0 a0[], 
                       A1 a1[], 
                       A2 a2[], 
                       A3 a3[], 
                       A4 a4[],
                       const int recordCount, 
                       int order)
    {
        std::function<int (A0, int, int)> indexFunc = (order == 1) ? (indexOfSmallest) : (indexOfSmallest);
    
        int indexOfNext;
    
        for (int index = 0; index < recordCount - 1; index++) {
            indexOfNext = indexFunc(a0, index, recordCount);
            // ...
        }
    }
    

    【讨论】:

    • 可以在函数内声明吗?
    • 添加第三个带有局部函数变量的示例。虽然我不认为这将是一个巨大的性能改进,因为它为分支交换了间接性。处理器非常擅长预测分支,因此我建议对其进行分析。
    • 所有这些都对 C++11 有好处,但不适用于旧的东西
    • 第一个模板参数解决方案也适用于 C++03,这就是 STL 算法的工作原理。您可以在 C++03 上使用 boost::function,而不是 std::function,定义一个函数指针或使用带有模板参数的第一个版本,并使用调用它的顺序定义一个额外的重载。
    【解决方案2】:

    函数模板不是函数。您不能形成指向函数模板的指针或将其作为参数传递给函数。但是,您似乎并不真正需要它来完成这项任务。你这样做

    template<typename A0, typename A1, typename A2, typename A3, typename A4>
    void sortArrayData(A0 a0[], A1 a1[], A2 a2[], A3 a3[], A4 a4[],
            const int recordCount, 
            int (*func)(A0[], int, int)) { ...
    

    然后像函数一样传递indexOfLargest 或indexOfSmallest。系统会自动选择正确的实例化。一个简化的例子是这样的:

    #include <iostream>
    using namespace std;
    
    template <class x> void xxx (x xx){cout << xx << endl; }
    
    void foo(void (*f)(int)) {f(5);}
    
    int main() {
        foo(xxx);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-18
      • 2010-11-19
      • 2013-04-30
      • 1970-01-01
      • 1970-01-01
      • 2011-12-09
      • 1970-01-01
      • 2015-04-26
      相关资源
      最近更新 更多