命名元组元素

时间:2015-07-03 12:24:35

标签: c++ templates c++14 template-meta-programming

我正在开发某种元组结构,我想允许用户将其元素用作字段,

解释:

这是我的元组:

template<typename ...Ts>
struct myTuple{
   std::tuple<Ts...> data;

   template<size_t I>
   inline type<I>& get_t() {   // type<I> is the I'th type
      return std::get<I>(data);
   }

   // Other stuff
};

目前用户可以这样:

struct UserStruct{
   myTuple<int,bool,string> t;
   // Other stuff
}

并使用它,

UserStruct ob;
ob.t.get_t<0>() = 0;

这有点复杂......所以我这样做了

struct UserStruct{
   myTuple<int,bool,string> t;

   decltype(mo.get_t<0>()) myInt() {
      return mo.get_t<0>();
   }

   decltype(t.get_t<1>()) myChar() {
      return t.get_t<1>();
   }

   decltype(t.get_t<2>()) myString() {
      return t.get_t<2>();
   }
};

所以他可以直接使用它:myInt()= 0;

我的目标是他可以使用元组,好像他有一个int, bool, string数据成员而不存储引用,这意味着我需要一个函数(或函子)来获取参考,所以我的解决方案很好,但它需要用户定义功能。 (并且实际代码中的getter看起来更糟)

所以我想要这样的事情:

struct UserStruct{
   myTuple<int,bool,string> t;

   MyFunctor<0> myInt;   //or an alias to a function

   MyFunctor<1> myChar;

   MyFunctor<2> myString;
};

2 个答案:

答案 0 :(得分:2)

MyFunctor<0> myInt;这样的代码在没有向仿函数提供t的情况下也无法工作,因此它知道要链接到哪个元组。但是,您可以添加一个宏来为您构建访问器,它将假定元组名称为t(或者您将其提供给宏)。

#define LINK_MEMBER(ID, NAME) decltype(t.get_t<ID>()) NAME() {  \
  return t.get_t<ID>();                                         \
}

然后你的代码看起来像

struct UserStruct{
   myTuple<int,bool,string> t;
   LINK_MEMBER(0, myInt);   //or an alias to a function
   LINK_MEMBER(1, myChar);
   LINK_MEMBER(2, myString);
};

答案 1 :(得分:0)

为什么在写myInt()时写my<int>()?这是另外一个角色,允许你只写:

template<typename ...Ts>
struct myTuple{
    std::tuple<Ts...> data;

    template <size_t I>
    decltype(auto) my() { return std::get<I>(data); }

    template <typename T>
    decltype(auto) my() { return std::get<T>(data); }
};

using UserStruct = myTuple<int, bool, std::string>;

不需要别名函数,宏等,同时也很简洁。