2015-07-03 74 views
4

我深化发展一个某种形式的元组结构,我想允许用户使用其元素领域,命名元组元素

解释:

这是我的元组:

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>(); 
    } 
}; 

这样他就可以直接使用它:敏()= 0;

我的目标是,他可以使用元组,如果他有一个int, bool, string数据成员不存储引用,这意味着我需要一个函数(或仿函数)来获得引用,所以我的解决方案是好的,但它需要用户定义功能。 (和吸气剂真正的代码看起来更糟糕)

所以我想是这样的:

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

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

    MyFunctor<1> myChar; 

    MyFunctor<2> myString; 
}; 
+0

你可以使用C++ 14吗?它有'std :: get ()'。 – Biffen

+0

我已经在使用它,我添加了标签 –

+2

如果元组有2个字符串或2个字符或2个整数会怎么样?你将如何区分它们?我对Herb Sutter有一个模糊的记忆,内容是关于将来的C++版本允许别名用于std :: get,所以你可以命名索引。我不确定它的情况。 – Robinson

回答

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); 
}; 
+0

谢谢你,我会用这个,直到我找到一个没有宏的解决方案 –

+2

在我看来,你也可以为结构的整个主体制作更宏伟的宏,你会像'BUILD_MEMBERS(int,myInt,char, myChar,string,myString);'然后它可以为你组装元组,你只需要担心命名每个条目并指出它是类型。 (如果我可以跨越多行,这看起来会好得多。) –

+0

我需要一个带可变参数的宏 –

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>; 

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

+0

myInt只是一个例子,我的意思是一种让用户命名访问者的方法。这正是元组的问题,这是人们想给他们的变量赋予一些意义,而不是使用获得

+0

@OthmanBenchekroun如果你想给出有意义的名字,只需写一个struct:struct UserStruct {int myInt; bool myBool;字符串myString; };'为什么你甚至需要'tuple'? – Barry

+0

这是一个特殊的结构,我需要直系 –