【问题标题】:Building a variadic template class with a set of function overloads based on the template arguments?使用基于模板参数的一组函数重载构建可变参数模板类?
【发布时间】:2019-08-25 09:06:41
【问题描述】:

动机:我需要为 C++17 库构建一个基类,该库将根据用户在编译时识别的类型对虚函数进行重载。基本上,当在基类上调用函数的特定重载时,我想确保在派生类中调用正确的版本。我最初的直觉是构建一个虚拟模板函数,但当然 C++ 不允许这样做,因为编译器不知道将它的哪个版本放入虚拟函数表中。但是,由于我会在编译时知道所有类型,是否可以使基类本身成为可变参数模板并使用模板参数来构建所需的一组重载版本的虚函数?

折叠表达式是正确的,因为它们不能用于声明函数。递归模板看起来很有希望,但我担心基类的长链继承会影响性能。这是我拥有的工作代码:

template <typename... Ts> class MyClass;

template <typename T, typename... Ts>
struct MyClass<T, Ts...> : public MyClass<Ts...> {
  using MyClass<Ts...>::MyFunction;
  virtual bool MyFunction(T in) { return true; }
};

template <>
struct MyClass<> {
  virtual bool MyFunction(...) { return false; }
};

这种技术应该足够了吗?或者有没有人对我如何实现这个目标有其他想法?

我的其他想法包括:

  • 限制可以处理和启用的模板参数的数量 - 如果每个重载基于参数列表是否足够长以包含它。缺点:这种技术会任意限制类型的数量。

  • 使用可变参数宏来构建类。缺点:这种技术会令人困惑和不优雅。

  • 创建一个函数以将类型分配给基类中的 ID 号,将其作为 void * 及其 id 传递给派生类,然后将其转换回该点以进行适当的重载调用.缺点:这种技术很难保证类型安全并尽量减少最终用户需要做的工作量。

现在我倾向于实现这些替代方案中的第一个并进行一些性能测试以将其与我的工作版本进行比较,但如果有一些我缺少的更清洁的东西我会很高兴。

【问题讨论】:

    标签: c++ inheritance overloading c++17 variadic-templates


    【解决方案1】:

    您的实现适合 C++14。

    C++17 允许可变参数using,以避免递归:

    template <typename T>
    struct MyClassImpl
    {
        virtual ~MyClassImpl() = default;
        virtual bool MyFunction(T in) = 0; // or { return true; }
    };
    
    template <typename... Ts>
    struct MyClass : public MyClassImpl<Ts>...
    {
        using MyClassImpl<Ts>::MyFunction...;
    };
    

    Demo

    【讨论】:

    • 谢谢!这正是我所需要的——我希望有一些我不知道的新功能。我也没有意识到你可以像这样一次解压所有的基类。
    猜你喜欢
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    相关资源
    最近更新 更多