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

C++ Single function pointer for all template instances

本文关键字:单个 函数 指针 实例 C++      更新时间:2023-10-16

有没有一种简洁的方法可以在不使用宏的情况下指向模板化函数的所有实例?

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

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的问题之外。这个问题(如何定义具有模板参数的函数指针的typedef)解释了如何定义指向模板化函数的指针;但是,要求指定模板参数。


为了澄清:假设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);

您试图用实现的目标

void testAcrossTypes(SomeType f) {
  f<int> ();
  f<bool> ();
  f<char> ();
  f<double> ();
}

如果CCD_ 12可以是模板模板参数。但是,该标准不允许函数模板作为模板模板参数。

来自C++11标准:

14.3.3模板模板参数

1模板模板参数的模板参数应为类模板或别名模板的名称,表示为id表达式。

最好的选择是使用函子而不是函数。示例:

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>();
}

您可以通过一个类型擦除的函子来完成它,比如下面的例子:

#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个调用
此外,您不需要在一堆结构中移动函数就可以使用它们。