1

i have a list like follows

my_mixed_list = {"Sample String", int_value, user_data_type}

I want to use C++11 std::tuple to display above list in simple white separated way. may be like this:

template <typename T>
    void display_mixed_items (std::tuple <T> mixed) {
         for (const auto& mixed_ele : mixed) std::cout << mixed_ele << " ";
}

I am aware that i would have to overload ostream operator to display the user defined data. But i hope you get the question. I'm not sure why compiler complains about argument list. what is proper way to accomplish above task. couldn't find exact answer on Stackoverflow so to mention.

in Python we could simple use list and tada! But if not tuple is there any other way to this may be using variadic templates or something.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
Amaresh Kumar
  • 586
  • 1
  • 8
  • 20
  • See this [question](https://stackoverflow.com/questions/1198260/how-can-you-iterate-over-the-elements-of-an-stdtuple). It should help. – cigien Jun 27 '20 at 13:12
  • `T` is one type. This template will accept a tuple of only one type. Furthermore, the `for` loop doesn't work with tuples, like this. Looks like you need to [review the relevant chapter in your C++ textbook](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Sam Varshavchik Jun 27 '20 at 13:13
  • yeah i forgot to read book! thanks for reminding. lol. i have updated the question though – Amaresh Kumar Jun 27 '20 at 13:19

2 Answers2

2

You can get by creating your own for_tuple function to iterate over tuples:

template<typename T, typename F, std::size_t... S>
void for_tuple_impl(std::index_sequence<S...>, T&& tup, F& function) {
    using expand_t = int[];
    (void) expand_t{(void(function(std::get<S>(std::forward<T>(tup)))), 0)..., 0};
}

template<typename T, typename F>
void for_tuple(T&& tup, F function) {
    for_tuple_impl(
        std::make_index_sequence<std::tuple_size<std::decay_t<T>>::value>{},
        std::forward<T>(tup),
        function
    );
}

Then use it like this:

for_tuple(my_tuple, [](auto&& mixed_ele){ std::cout << mixed_ele << ' '; });

C++23 wants to make a language feature called a template for to replace that pile of brakets and parens (not official yet):

template for (auto&& mixed_ele : mixed) {
    std::cout << mixed_ele << ' ';
}
Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
  • i mean i know i think i would need to create an enum with these diff data types, but is there any C++ construct to do without using enum data type for the purpose – Amaresh Kumar Jun 27 '20 at 14:03
1

Use the now-famous "for each argument" by Sean Parent:

template <class F, class... Args>
void for_each_argument(F f, Args&&... args) {
    [](...){}((f(std::forward<Args>(args)), 0)...);
}

with f being something which streams your arguments to std::cout.

See also:

How can you iterate over the elements of an std::tuple?

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • gonna try right now. thanks. i see you have combined lambdas and forward. have to grasp a lot – Amaresh Kumar Jun 27 '20 at 13:19
  • 2
    You should use an initializer-list, otherwise the order of evaluation is unspecified (which is not good for streaming to the console). – cigien Jun 27 '20 at 13:22
  • 1
    @cigien: Wait. Why? We're not initializing an object here, we're using an IILE. Or do you mean outside of `for_each_argument`? – einpoklum Jun 27 '20 at 13:33
  • I mean around the expansion of `f`. Basically like Guillaume's answer. – cigien Jun 27 '20 at 13:36