Generic printing of 2D containers

Asked by At

this template prints the content of an 2D vector

how would you generalize this template so it works for every STL container ?

template<class T> void printVector(std::vector<std::vector<T>> const &matrix) { for (std::vector<T> row : matrix) { for (T val : row) { std::cout << val << " "; } std::cout << '\n'; } }

Is there maybe "print" that allows me to print anything, no matter what I put into it ? (n-dimensional containers, strings, etc ?)

2 Answers

3
Ben. Ayoub On Best Solutions

Is there maybe "print" that allows me to print anything, no matter what I put into it ? (n-dimensional containers, strings, etc ?)

yes, I have made in one of my projects to recursively print very nested trees that represent AST

We need to do some template tricks to determine whether a nested element is another container, a pointer, an optional type, a variant type or something else.

C++ does not have reflection, so if at any point we encounter a user-defined type will have a problem since (currently) there is no way to obtain information about given type members. Unless we register it with BOOST_FUSION_ADAPT_STRUCT.

The "thing" is quite large so better read the code from repo directly.

The class is used like this: structure_printer()(object). First () is ctor, second one is operator() that will recursively call it again with sub-elements.

The structure it prints is very similar to JSON format.

Nonetheless : Here's a simple solution for 2D container:

template <typename Matrix>
void printMatrix(Matrix const& matr) {
  for (auto const& row : matr) {
    for (auto const& val : row)
      std::cout << val << ' ';

    std::cout << '\n';
  }
}
1
Cruz Jean On

Just take any type and use range based loops. Your only problem is that you specified that is was a std::vector.

template<class T>
void print2Dcontainer(const T &matrix)
{
    for (const auto &row : matrix)
    {
        for (const auto &val : row) std::cout << val << ' ';
        std::cout << '\n';
    }
}

My version above has no safety for passing something that will cause a compile error (e.g. passing 7). Fancy SFINAE could be added to remove this potential issue, but I'd only do so for library code.