重载operator << for std :: tuple - 可能的简化?

Fah*_*tha 7 c++ templates tuples c++11 iterable-unpacking

我使用 SO问题的答案"迭代元组"来编写一个重载方法<<.这个方法经过测试,似乎可以g++ 4.7在Debian squeeze上正常工作.

然而,这种方法有点迂回,因为它似乎<<无法明确实例化(我在这里发现了一篇关于它的帖子 ).因此,一个人被迫定义一个字符串方法,然后调用它.我有一个类似的矢量方法,更直接.有没有人建议如何消除创建字符串方法的额外步骤,使用相同的方法,或其他?提前致谢.

#include <tuple>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>

using std::ostream;
using std::cout;
using std::endl;
using std::vector;
using std::string;

// Print vector<T>.
template<typename T> ostream& operator <<(ostream& out, const vector<T> & vec)
{
  unsigned int i;
  out << "[";
  for(i=0; i<vec.size(); i++)
    {
      out << vec[i];
      if(i < vec.size() - 1)
    out << ", ";
    }
  out << "]";
  return out;
}

////////////////////////////////////////////////////////////////

// Print tuple.
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), string>::type
stringval(const std::tuple<Tp...> & t)
{
  std::stringstream buffer;
  buffer << "]";
  return buffer.str();
}

template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), string>::type
stringval(const std::tuple<Tp...> & t)
{
  std::stringstream buffer;
  size_t len = sizeof...(Tp);
  if(I==0)
      buffer << "[";
  buffer << std::get<I>(t);
  if(I < len - 1)
    buffer << ", ";
  buffer << stringval<I + 1, Tp...>(t);
  return buffer.str();
}

template<typename... Tp> ostream& operator <<(ostream& out, const std::tuple<Tp...> & t)
{
  out << stringval(t);
  return out;
}

int
main()
{
  typedef std::tuple<int, float, double> T;
  std::tuple<int, float, double> t = std::make_tuple(2, 3.14159F, 2345.678);
  cout << t << endl;
}
Run Code Online (Sandbox Code Playgroud)

编译时,这给出了

[2, 3.14159, 2345.68]
Run Code Online (Sandbox Code Playgroud)

ken*_*ytm 5

您可以将传递给std::ostream&stringval函数并使用out <<代替buffer <<

演示

#include <tuple>
#include <iostream>
#include <type_traits>

template <size_t n, typename... T>
typename std::enable_if<(n >= sizeof...(T))>::type
    print_tuple(std::ostream&, const std::tuple<T...>&)
{}

template <size_t n, typename... T>
typename std::enable_if<(n < sizeof...(T))>::type
    print_tuple(std::ostream& os, const std::tuple<T...>& tup)
{
    if (n != 0)
        os << ", ";
    os << std::get<n>(tup);
    print_tuple<n+1>(os, tup);
}

template <typename... T>
std::ostream& operator<<(std::ostream& os, const std::tuple<T...>& tup)
{
    os << "[";
    print_tuple<0>(os, tup);
    return os << "]";
}
Run Code Online (Sandbox Code Playgroud)