可变参数模板的代码大小问题

Code size concerns with variadic templates

我正在创建一种算法,可以同时处理许多不同的用户定义类型。假定这些类型中的每一个都具有 func1func2,它们将成为 MyAlgorithm 的接口。我可以使用可变模板来做到这一点:

template <typename... Args>
class MyAlgorithm{
    // interact with Args using func1 and func2
};

我现在可以像这样实例化 MyAlgorithm MyAlgorithm<A, B, C, D, E, F, G>。这行得通,但是,我觉得对于我的应用程序来说,这可能会导致 MyAlgorithm 的专业化过多。实际上,MyAlgorithm可能像MyAlgorithm<A, B, B , A, C, D>一样先被实例化,然后是MyAlgorithm<A, A, C, D>,然后是MyAlgorithm<C, F D>,依此类推。

不幸的是,模板是针对 Args 的每个组合实例化的。这会产生问题,例如,在在线设置中。 MyAlgorithm 可能是 运行 批量实时输入数据(MyAlgorithm 的性质是它 运行 批量而不是单个输入)。将解析实时输入数据并调用 MyAlgorithm 的正确特化。在这种情况下,用户将需要在编译代码中创建 MyAlgorithm 所有可能的特化。

MyAlgorithm<A>;
MyAlgorithm<B>;
MyAlgorithm<C>;
MyAlgorithm<A, A>;
MyAlgorithm<A, B>;
MyAlgorithm<A, C>;
MyAlgorithm<B, A>;
...

我有一个想法可能会有所帮助,但我没有完全正确。而不是 MyAlgorithm 采用模板参数,它将处理专门用于 A, B, Cs.

的模板 Proxy class
// no template 
class MyAlgorithm{
    // interact with Proxy using func1proxy and func2proxy
    std::vector<Proxy> Args;
};

template<typename T>
class Proxy{
    // define func1proxy and func2proxy using Arg's func1 and func2
    std::unique_ptr<T> Arg; // only member
};

当然这是行不通的,因为每个 Proxy 专业化都是不同的 class 所以 MyAlgorithm 仍然需要是一个模板 class (并且 std::vector<Proxy> Args 不存在)。

我想做的事情有设计模式吗?是否有一种设计模式可以减少 class 实例化的数量?

一些注意事项:

MyAlgorithm 对所有模板参数一视同仁。该算法在每个模板参数上递归调用 func1func2

class MyAlgorithm{
    template<typname T, typename... Args>
    void CallFunc1s(T first, Args... rest){
        T.func1();
        SomeFunction(rest);
    }
};

类型擦除 func1/func2 调用的类型 T。

struct proxy_ref{
  void* pdata=0;
  void(*pfunc1)(void*)=0;
  void(*pfunc2)(void*)=0;
  template<class T>
  proxy_ref(T&& t):
    pdata((void*)std::addressof(t)),
    pfunc1([](void*pvoid){
      ((T*)pvoid)->func1();
    }),
    pfunc2([](void*pvoid){
      ((T*)pvoid)->func2();
    })
  {}
  void func1(){ pfunc1(pvoid); }
  void func2(){ pfunc2(pvoid); }
};

现在获取 proxy_ref 的矢量,并在其上调用 func1func2

您的特定问题可能涉及更复杂的签名,甚至是值类型而不是引用类型。

像你这样的问题类型擦除无法解决,但尝试这是第一步。