简体   繁体   English

使用二进制搜索进行模板递归

[英]Template recursion using binary search

Consider this working code I wrote: 考虑一下我编写的以下工作代码:

#include <iostream>

constexpr int MIN_FOO = 0,  MAX_FOO = 100;

template <int N>
void foo() {std::cout << "foo<" << N << ">() called.\n";}

template <int N>
void foo (char, double, bool) {std::cout << "foo<" << N << ">(char, double, bool) called.\n";}


template <int Low, int High, typename... Args>
void searchFooBinary (int key, Args... args) {
//  if (LOW > HIGH) {std::cout << "Error with searchFooBinary.\n";  return;}
    constexpr int Mid = (Low + High) /2;
    if (key == Mid)
        foo<Mid>(std::forward<Args>(args)...);  // Want to generalize this using 'f'.
    else if (key < Mid)
        searchFooBinary<Low, Mid - 1>(key, std::forward<Args>(args)...);
    else
        searchFooBinary<Mid + 1, High>(key, std::forward<Args>(args)...);
}

template <typename... Args>
void executeFooBinarySearch (int n, Args... args) {
    searchFooBinary<MIN_FOO, MAX_FOO>(n, std::forward<Args>(args)...);
}

int main() {
    executeFooBinarySearch(99);
    executeFooBinarySearch (99, 'a', 1.5, true);
}

So foo is a template function and here a run-time int is passed and searchFooBinary uses a binary search to find the correct int value for the template argument. 因此foo是模板函数,在这里传递了运行时int,而searchFooBinary使用二进制搜索来找到template参数的正确int值。 So far so good, but I don't want to write this binary search function for every new function like foo . 到目前为止,一切都很好,但是我不想为每个新函数(如foo编写此二进制搜索函数。 How do I generalize the use of foo in searchFooBinary to the more general f ? 如何将在searchFooBinary使用foo推广到更通用的f If a template function pointer is not allowed, what would be a workaround to achieve this goal? 如果不允许使用模板函数指针,那么实现此目标的解决方法是什么?

How about using a functor: 如何使用函子:

#include <iostream>

constexpr int MIN_FOO = 0,  MAX_FOO = 100;

struct Foo
{
    template <int N>
    void operator() (char, double, bool) {std::cout << "Foo<" << N << ">(char, double, bool) called.\n";}
};

struct Bar
{
    template <int N>
    void operator() () {std::cout << "Bar<" << N << ">() called.\n";}   
};


template <int Low, int High, typename Fun, typename... Args>
void searchBinary (int key, Fun f, Args... args)
{
    constexpr int Mid = (Low + High) /2;
    if (key == Mid)
    {
        f.template operator()<Mid>(std::forward<Args>(args)...);
    }
    else if (key < Mid)
    {
        searchBinary<Low, Mid - 1>(key, f, std::forward<Args>(args)...);
    }
    else
    {
        searchBinary<Mid + 1, High>(key, f, std::forward<Args>(args)...);
    }
}

template <typename Fun, typename... Args>
void executeBinarySearch (int n, Fun f, Args... args)
{
    searchBinary<MIN_FOO, MAX_FOO, Fun>(n, f, std::forward<Args>(args)...);
}

int main()
{
    executeBinarySearch (99, Foo(), 'a', 1.5, true);
    executeBinarySearch (99, Bar());    
}

output 输出

Foo<99>(char, double, bool) called.
Bar<99>() called.

Live example: http://ideone.com/fSoG5B 实时示例: http//ideone.com/fSoG5B

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM