C ++所有模板实例的单一函数指针

时间:2016-07-21 03:13:30

标签: c++ templates macros function-pointers

是否有简明的方法指向模板化函数的所有实例而不使用宏?

我有几个模板化的函数,我想测试各种类型:

template<typename T>
void function1() {
  return;
}

template<typename T>
void function2() {
  return;
}

template<typename T>
void function3() {
  return;
}

我可以用宏来做到这一点:

#define TEST_ACROSS_TYPES(fn) \
fn<int>();  \
fn<bool>(); \
fn<char>(); \
fn<double>(); \

TEST_ACROSS_TYPES(function1);
TEST_ACROSS_TYPES(function2);

但是,(1)宏很丑,很难让其他人遵循,(2)我使用的是CATCH,当使用宏设置测试用例时,它并不好玩

有没有办法做这样的事情:

void testAcrossTypes(SomeType f) {
  f<int> ();
  f<bool> ();
  f<char> ();
  f<double> ();
}
除了定义SomeType的问题外,

似乎更清晰。这个问题(How to define typedef of function pointer which has template arguments)解释了如何定义指向模板化函数的指针;但是,要求指定模板参数。

澄清:想象function1function2function3各自测试不同的模板化函数。每个函数都需要针对intbytechardouble等进行测试。我希望避免显式设置多个(即num_functions * num_types)测试对于每个功能。相反,我希望有一个指向测试函数的方法(function1function2等)并为每个模板类型运行它,从而整合

function1<int>();
function1<byte>();
function1<char>();
function1<double();
...
function2<int>();
function2<byte>();
function2<char>();
function2<double();
...
function3<int>();
function3<byte>();
function3<char>();
function3<double();
...

每个测试函数只需一次调用

testAcrossTypes(function1);
testAcrossTypes(function2);
testAcrossTypes(function3);

2 个答案:

答案 0 :(得分:5)

你想用

完成什么
void testAcrossTypes(SomeType f) {
  f<int> ();
  f<bool> ();
  f<char> ();
  f<double> ();
}
如果SomeType可以是模板模板参数,则可以

。但是,该标准不允许将函数模板用作模板模板参数。

来自C ++ 11标准:

  

14.3.3模板模板参数

     

1模板模板参数的 template-argument 应为类模板或别名模板的名称,表示为id-expression。

您最好的选择是使用仿函数而不是函数。例如:

template<typename T>
struct function1
{
   void operator()() {
      return;
   }
};

template<typename T>
struct function2
{
   void operator()() {
      return;
   }
};

template < template <typename> class F>
void testAcrossTypes() {
  F<int>()();
  F<bool>()();
  F<char>()();
  F<double>()();
}

int main()
{
   testAcrossTypes<function1>();
   testAcrossTypes<function2>();
}

答案 1 :(得分:3)

您可以通过类型擦除的仿函数来完成它,如下例所示:

#include<vector>

template<typename T>
void function1() { }

template<typename T>
void function2() { }

template<typename T>
void function3() { }

struct Test {
    template<typename T>
    static void proto() {
        function1<T>();
        function2<T>();
        function3<T>();
    }

    void operator()() {
        for(auto &f: vec) f();
    }

    template<typename... T>
    static Test create() {
        Test test;
        int arr[] = { (test.vec.emplace_back(&proto<T>), 0)... };
        (void)arr;
        return test;
    }

    using func = void(*)(void);
    std::vector<func> vec;
};

void testAcrossTypes(Test test) {
    test();
}

int main() {
    testAcrossTypes(Test::create<int, bool, char, double>());
}

在这两种情况下都很容易修改:

  • 新功能需要添加到proto静态成员方法,而且全部

  • 添加新类型是在调用create时使用它的问题,如上例所示

仿函数将负责创建要执行的N * M次呼叫 而且,您不需要在一堆结构中移动函数以便能够使用它们。