在 c++14 中从可变参数模板类调用基函数

Calling base function from variadic template class in c++14

提问人:arek 提问时间:6/23/2023 更新时间:6/23/2023 访问量:40

问:

我的类结构如下。 如何从所有基类的 MultiBase 类调用函数。有没有办法遍历参数包中的参数?

template <typename T, typename... Args>
class Base : public Base<T>{
};

template <typename T>
class Base<T> {

    protected:
       void test()
       {
         std::cout << typeid(m_data).name() << std::endl;
       }
       void insert(T data)
       {
           m_data = data;
       }
    private:
      T m_data;
};

template<typename T, typename ...Args>
class MultiBase : public Base<T, Args...>
{
    public:
    template<typename V>
    void insert(ClientId key, V data)
    {
        Base<V>::insert(key, data);
    }

    void f()
    {
        // call test() from Base class for all types from parameter pack
    }
};


int main()
{
    MultiBase<int,float> ms;
    ms.f() // equivalent to calling Base<int>::test() and Base<std::string>::test()
    return 0;
}

提前感谢您的帮助。

模板 C++14 可变模板

评论


答:

1赞 maxplus 6/23/2023 #1

您的代码有很多问题,例如类只有一个基。但要回答眼前的问题:您可以使用包扩展。我提供了两个示例:大括号括起来的初始值设定项列表中的扩展和模板参数列表中的扩展,以及 c++17 的奖励示例。MultiBase

#include <iostream>
#include <type_traits>

template <typename Value>
class Base {
protected:
  void test() {
    std::cout << typeid(Value).name() << std::endl;
  }
};

template <typename... Values>
class MultiBase : public Base<Values>... {
public:
  void f() {
    // hacky solution:
    int unused[]{(Base<Values>::test(), 0)...};

    // generic recursive solution:
    f_impl<Values...>();

    // c++17 simplifies this with fold-expressions:
    // (Base<Values>::test(), ...);
  }

private:
  template <typename First, typename... Others>
  void f_impl() {
    Base<First>::test();
    f_impl<Others...>();
  }
  
  // overload to terminate recursion,
  // SFINAE to only be eligible for empty parameter pack
  template <typename... Others, typename = std::enable_if_t<sizeof...(Others) == 0>>
  void f_impl() {
  }
};

int main() {
  MultiBase<int, float, const char*> ms;
  ms.f();
  return 0;
}