Skip to content
Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

How to print anything in C++ (part 3)

elbeno, 2 February, 201530 June, 2015

Part 1 Part 2 Part 3 Part 4 Part 5 Postscript

So far, we’ve dealt with things that are already outputtable with operator<<, and things that are iterable with begin() and end(). To round out the “containers”, we need to deal with pair and tuple. It’s simple to print a pair:

template 
struct stringifier_select
{
  explicit stringifier_select(const T& t) : m_t(t) {}

  std::ostream& output(std::ostream& s) const
  {
    return s << '(' << prettyprint(m_t.first)
             << ',' << prettyprint(m_t.second) << ')';
  }

  const T& m_t;
};

Printing a tuple is a little harder. There is no easy way to iterate through a tuple, but that's what we want to do. A tuple is designed for compile-time member access where you know either the index (from C++11) or the type (from C++14) of the element you want. So what we need is a compile-time way of iterating through an index. And that's what std::index_sequence is for.

template 
inline void for_each_in_tuple(const std::tuple& t,
                              F f,
                              std::index_sequence)
{
  (void)(int[]) { 0, (f(std::get(t), Is), 0)... };
}
template 
inline void for_each_in_tuple(const std::tuple& t, F f)
{
  for_each_in_tuple(t, f, std::make_index_sequence());
}

This is a handy function to have around. It applies a function to each element of a tuple. First (in the second function seen here), we create a std::index_sequence equal to the size of the tuple. Then (in the top function) we construct an int array using uniform initialization. To deal with zero-length tuples, the array has one zero element to begin. After that, each element of the array is our function applied to the thing at the current index and the index itself, sequenced with zero using the comma operator, so that whatever is returned, the array gets a zero and is happy.

I decided to pass both the element and the index to the function to deal with the separator fencepost problem (as with containers). So outputting a tuple looks like this:

template 
struct stringifier_select
{
  explicit stringifier_select(const T& t) : m_t(t) {}

  std::ostream& output(std::ostream& s) const
  {
    s << '(';
    for_each_in_tuple(m_t,
                      [&s] (auto& e, size_t i)
                      { if (i > 0) s << ',';
                        s << prettyprint(e); });
    return s << ')';
  }

  const T& m_t;
};

Going well so far. Next, I'll look at distinguishing callable things.

C++ Programming

Post navigation

Previous post
Next post

Related Posts

Experimenting with constexpr

13 October, 201515 October, 2015

Since seeing Scott Schurr at C++Now in Aspen and hearing his talks about constexpr, it’s been on my list of things to try out, and recently I got around to it. With the release of Visual Studio 2015, Microsoft’s compiler now finally supports C++11 style constexpr (modulo some minor issues),…

Read More

std::source_location is Broken

16 November, 202316 November, 2023

Everyone knows that the best way to get something done on the Internet is with an inflammatory title and a potentially incorrect contention, so here goes. What do you if you want to capture/log the filename of an assertion? Prior to C++20, you use good old __FILE__, which gives you…

Read More

C++11 compile-time string hashing

13 October, 201515 October, 2015

(Start at the beginning of the series – and all the source can be found in my github repo) Now that I was used to writing C++11-style constexpr, I decided to try some compile-time string hashing. It turns out that FNV1 is very easy to express in a move-down-the-string recursive…

Read More

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

©2026 Why is a raven like a writing desk? | WordPress Theme by SuperbThemes