fork download
  1. #include <iostream>
  2.  
  3. // Contains the actual value for one item in the tuple. The
  4. // template parameter `i` allows the
  5. // `Get` function to find the value in O(1) time
  6. template<std::size_t i, typename Item>
  7. struct TupleLeaf {
  8. Item value;
  9. };
  10.  
  11. // TupleImpl is a proxy for the final class that has an extra
  12. // template parameter `i`.
  13. template<std::size_t i, typename... Items>
  14. struct TupleImpl;
  15.  
  16. // Base case: empty tuple
  17. template<std::size_t i>
  18. struct TupleImpl<i>{};
  19.  
  20. // Recursive specialization
  21. template<std::size_t i, typename HeadItem, typename... TailItems>
  22. struct TupleImpl<i, HeadItem, TailItems...> :
  23. public TupleLeaf<i, HeadItem>, // This adds a `value` member of type HeadItem
  24. public TupleImpl<i + 1, TailItems...> // This recurses
  25. {};
  26.  
  27. // Obtain a reference to i-th item in a tuple
  28. template<std::size_t i, typename HeadItem, typename... TailItems>
  29. HeadItem& Get(TupleImpl<i, HeadItem, TailItems...>& tuple) {
  30. // Fully qualified name for the member, to find the right one
  31. // (they are all called `value`).
  32. return tuple.TupleLeaf<i, HeadItem>::value;
  33. }
  34.  
  35. // Templated alias to avoid having to specify `i = 0`
  36. template<typename... Items>
  37. using Tuple = TupleImpl<0, Items...>;
  38.  
  39. int main(int argc, char** argv) {
  40. Tuple<int, float, std::string> tuple;
  41. Get<0>(tuple) = 5;
  42. Get<1>(tuple) = 8.3;
  43. Get<2>(tuple) = "Foo";
  44. std::cout << Get<0>(tuple) << std::endl;
  45. std::cout << Get<1>(tuple) << std::endl;
  46. std::cout << Get<2>(tuple) << std::endl;
  47. return 0;
  48. }
Success #stdin #stdout 0s 4436KB
stdin
Standard input is empty
stdout
5
8.3
Foo