【问题标题】:Variadic templates & multiple inheritance可变参数模板和多重继承
【发布时间】:2014-05-15 14:22:13
【问题描述】:

我正在为可变参数模板的多重继承而苦苦挣扎。

这是我目前的代码:

template <typename U>
    class id_map {
    public:
    std::vector<U> vec_;
};

现在我要初始化另一个类,它从 id_map 继承多次,如下所示:

template<typename ... T>
class constant_allkey_map : public id_map<T> ... {
private:
public:
    template <typename U>
    void push_back(U i) {
        id_map<U>::vec_.push_back(i);
    }
};

这行得通,我可以正常访问它:

constant_allkey_map<int, long> cakm;
cakm.push_back<int>(1);

当我尝试这样的事情时它失败了:

constant_allkey_map<int, int> cakm;

有错误

"duplicate base type id_map<int> invalid".

我做了一些阅读,似乎我应该使用 id 参数扩展 id_map 模板:

template <size_t i_, typename U>
class id_map ...

但我不确定如何在继承部分传递该 ID:

template<typename ... T>
class constant_allkey_map : public id_map<T> ... {

有人可以帮帮我吗?如果我这样做完全错误,请指出我正确的方向?

【问题讨论】:

  • cakmconstant_allkey_map&lt;int,int&gt; 时,您希望cakm.push_back(1); 做什么?
  • 我会很高兴 cakm.push_back(1);, cakm.push_back(1);就像使用元组一样,但不知道如何实现..基本上这是我的问题

标签: c++11 multiple-inheritance variadic-templates


【解决方案1】:

我不认为继承在这里是正确的。因此,我提出以下方法来实现您想要的:

#include <tuple>
#include <vector>

template <typename U>
class id_map
{
public:
  typedef U value_type;

public:
  std::vector<U> vec_;
};

template<typename... T>
class constant_allkey_map
{
private:
  typedef std::tuple<id_map<T>...> tuple_t;

public:
  template<
    std::size_t Idx,
    typename U = typename std::tuple_element<Idx, tuple_t>::type::value_type
  >
  void push_back(U x)
  {
    std::get<Idx>(maps_).vec_.push_back(x);
  }

  template<
    std::size_t Idx,
    typename U = typename std::tuple_element<Idx, tuple_t>::type::value_type
  >
  U get(int i) const
  {
    return std::get<Idx>(maps_).vec_[i];
  }

private:
  tuple_t maps_;
};

用法非常简单:

#include <iostream>

int main(int, char**)
{
  constant_allkey_map<int, long> cakm;
  cakm.push_back<0>(1);
  cakm.push_back<0>(3);
  cakm.push_back<1>(2);
  cakm.push_back<1>(4);

  std::cout << cakm.get<0>(0) << std::endl;
  std::cout << cakm.get<1>(0) << std::endl;
  std::cout << cakm.get<0>(1) << std::endl;
  std::cout << cakm.get<1>(1) << std::endl;
}

这是live example.

基本上你只是让std::tuple 为你做这些脏活。你甚至可以这样做:

template<typename... T>
using constant_allkey_map = std::tuple<std::vector<T>...>;

并直接使用 std::get。

【讨论】:

    猜你喜欢
    • 2016-06-20
    • 2015-11-10
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多