I am trying to make a template function call like this:
typedef std::tuple<int, double, bool> InstrumentTuple; Cache cache; InstrumentTuple tuple = cache.get<InstrumentTuple>();
I know that I can "just" pass the types of tuples. This is what I know, but it is rather cumbersome, since I make many calls to this function, and since the tuples are quite long:
InstrumentTuple tuple = c.get<int, double, bool>();
So, I tried several implementations of the get method, but without success:
Inclusion using a template parameter
#include <tuple> class Cache { private: template<int I, typename T, typename = typename std::enable_if<I == std::tuple_size<T>::value>::type> std::tuple<> get() // line 6 { return std::tuple<>(); } template<int I, typename T, typename = typename std::enable_if<I != std::tuple_size<T>::value>::type> std::tuple<typename std::tuple_element<I,T>::type, decltype(get<I+1, T>())> get() // line 12 { std::tuple<typename std::tuple_element<I,T>::type> value; return std::tuple_cat(value, get<I+1, T>()); } public: template<typename T> T get() { return get<0, T>(); // line 22 } }; int main(int argc, char** argv) { Cache cache; typedef std::tuple<int, double, bool> InstrumentTuple; InstrumentTuple tuple = cache.get<InstrumentTuple>(); // line 30 }
Which gives me this error:
main.cpp: In instantiation of 'T Cache::get() [with T = std::tuple<int, double, bool>]': main.cpp:30:56: required from here main.cpp:22:26: error: no matching function for call to 'Cache::get()' main.cpp:22:26: note: candidates are: main.cpp:6:18: note: template<int I, class T, class> std::tuple<> Cache::get() main.cpp:6:18: note: template argument deduction/substitution failed: main.cpp:5:33: error: no type named 'type' in 'struct std::enable_if<false, void>' main.cpp:12:81: note: template<int I, class T, class> std::tuple<typename std::tuple_element<I, T>::type, decltype (get<(I + 1), T>())> Cache::get()
I do not understand why the template parameter is missing.
So, I tried another implementation:
Template Named Parameter
#include <tuple> class Cache { private: template<int> std::tuple<> get() // line 7 { return std::tuple<>(); } template<int index, typename type, typename... rest> std::tuple<type, rest...> get() // line 13 { return std::tuple_cat(std::tuple<type>(), get<index+1, rest...>()); } public: template<template<typename... types> class tuple> typename std::tuple<(tuple::types)...> get() { return get<0, (tuple::types)...>(); } }; // line 24 int main(int argc, char** argv) { Cache cache; typedef std::tuple<int, double, bool> InstrumentTuple; InstrumentTuple tuple = cache.get<InstrumentTuple>(); // line 30 }
But then I get this error:
Again, I do not understand the error due to the missing identifier.
Now I wonder if what I want to achieve is even possible. Is it possible to use std::tuple as I want? Or is there a better way?