I have a tuple of elements that I want to access using std::get
with the type name:
template<typename... Params>
struct SomeType
{
std::tuple<Params...> params;
};
using TypeOne = SomeType<std::string, int, double>;
using TypeTwo = SomeType<std::string, std::string, int>;
using TypeThree = SomeType<std::string, int, double>;
...
std::tuple<TypeOne, TypeTwo, TypeThree> tuple;
//Works via index, but I want to use the type
auto first = std::get<0>(tuple);
auto second = std::get<1>(tuple);
auto third = std::get<2>(tuple);
//Doesn't work here since TypeOne and TypeThree are the same
auto onth = std::get<TypeOne>(tuple);
auto twoth = std::get<TypeTwo>(tuple);
auto threeth = std::get<TypeThree>(tuple);
My current resolution is to have the first parameter be a lambda type:
template<typename ID, typename... Params>
struct SomeTypeWithId
{
SomeTypeWithId(Params... _params)
: params(std::make_tuple(_params...))
{}
std::tuple<Params...> params;
};
using TypeOneWithID = SomeTypeWithId<decltype([](){}), std::string, int, double>;
using TypeTwoWithID = SomeTypeWithId<decltype([](){}), std::string, std::string, int>;
using TypeThreeWithID = SomeTypeWithId<decltype([](){}), std::string, int, double>;
std::tuple<TypeOneWithID, TypeTwoWithID, TypeThreeWithID> tuple;
//Works since they're all different types now
auto onth = std::get<TypeOneWithID>(tuple);
auto twoth = std::get<TypeTwoWithID>(tuple);
auto threeth = std::get<TypeThreeWithID>(tuple);
But the syntax here is annoying as I do not want to have to always have to put decltype([](){})
in all my using declaratives. I thought I could get away with something like this:
template<typename ID, typename... Params>
struct SomeTypeWithId;
template<typename... Params>
struct SomeTypeWithId<decltype([](){}), Params...>
{
SomeTypeWithId(Params... _params)
: params(std::make_tuple(_params...))
{}
std::tuple<Params...> params;
};
But it doesn't work. How can I achieve this? My issue is that the index of the elements will likely change (across various tuples), but their names will not.
You could just define types instead of making typedef
s:
template <class... Params>
struct SomeType {
std::tuple<Params...> params;
};
struct TypeOneWithID : SomeType<std::string, int, double> {};
struct TypeTwoWithID : SomeType<std::string, std::string, int> {};
struct TypeThreeWithID : SomeType<std::string, int, double> {};