2015-07-03 2 views
4

Я developping в какой-то структуры кортежа, и я хотел бы, чтобы позволить пользователю использовать его элементы в виде полей,Naming элементы кортежа

ОБЪЯСНЕНИЕ:

это мой кортеж:

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 интервала? Как вы будете различать их? У меня смутное воспоминание о Трабе Саттере о будущей версии C++, позволяющей использовать псевдонимы для std :: get, поэтому вы можете назвать индексы. Я не уверен, что с ним происходит. – Robinson

ответ

2

код как MyFunctor<0> myInt; не может работать без подачи т функтора, а поэтому знает, какие Кортеж для ссылки. Однако вы могли бы добавить макрос, чтобы построить для вас аксессор, который предположил бы, что имя кортежа равно 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 был всего лишь примером. То, что я имел в виду, это способ дать имя пользователю доступ к аксессуарам. Это точно проблема с кортежем, это то, что люди хотят дать некоторые значения для своих переменных, которые не используют get

+0

@OthmanBenchekroun Если вы хотите дать значимые имена, просто напишите struct: 'struct UserStruct {int myInt; bool myBool; string myString; }; 'Зачем вам нужен« кортеж »? – Barry

+0

Это особая структура, мне нужна общность –

Смежные вопросы