c – 使用operator <<是否有合法的方法来打印元组和对?

我有一组模板/函数允许我打印一个元组/对,假设元组/对中的每个类型都有运算符<<为它定义.不幸的是,由于17.4.3.1,添加我的运算符<<超载到标准.有没有其他方法让ADL找到我的操作符<<?如果没有,在命名空间std {}中包装我的重载是否有任何实际损害? 感兴趣的人的代码:(我正在使用 gcc-4.5)
namespace tuples {
  using ::std::tuple;
  using ::std::make_tuple;
  using ::std::get; 
namespace detail {

template< typename...args >
size_t size( tuple<args...> const& )
{
  return sizeof...(args);
};

template<size_t N>
struct for_each_ri_impl
{
  template<typename Func,typename Tuple>
  void operator()(Func func,Tuple const& arg)
  {
    for_each_ri_impl<N-1>()(func,arg );
    func( get<N>( arg ),size(arg) - N - 1 );
  }
};

template<>
struct for_each_ri_impl<0>
{
  template<typename Func,Tuple const& arg)
  {
    func( get<0>( arg ),size(arg) - 1 );
  }
};
}//detail

template<typename Func,typename ... Args>
void for_each_ri( tuple<Args...>const& tup,Func func )
{
  detail::for_each_ri_impl< sizeof...(Args)-1>()( func,tup );
}


struct printer {
  std::ostream& out;
  const std::string& str;
  explicit printer( std::ostream& out=std::cout,std::string const& str="," ) : out(out),str(str) { }

  template<typename T>void operator()(T const&t,size_t i=-1) const { out<<t; if(i) out<<str; }
};

//Should this next line go into namespace std? Is there another way?
template<typename ... Args>
std::ostream& operator<<(std::ostream& out,std::tuple< Args... > const& tup)
{
  out << '[';
  tuples::for_each_ri( tup,tuples::printer(out,",") );
  return out << ']';
}

} //tuples

//Edits --
int main()
{
using namespace std;

cout<<make_tuple(1,'a',"Hello")<<endl;

return 0;
}

编制以上产量:

test.cpp: In function ‘int main()’:
test.cpp:69:31: error: cannot bind ‘std::ostream’ lvalue to ‘std::basic_ostream&&’ > /opt/local/include/gcc45/c++/ostream:579:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT,_Traits>& std::operator<<(std::basic_ostream<_CharT,_Traits>&&,const _Tp&) [with _CharT = char,_Traits = std::char_traits,_Tp = std::tuple]’

解决方法

把你自己的光包装类放在它周围,然后重载operator<<使用它.但请注意,即使您的光包装器具有隐式构造函数,您仍可能需要在将其传递给operator<<
template< typename ...VA_ARGS >
    struct format_tuple
    {
       typedef tuple<VA_ARGS...> tuple_type;
    // any format variables
       const tuple_type & tup;
       format_tuple( const tuple_type& t): tup(t) {}
    };

    template< typename ...VA_ARGS > format_tuple<VA_ARGS...> makeFormatTuple( const tuple<VA_ARGS...> & t ) 
    {
       return format_tuple( t );
    }

    template<typename ...VA_ARGS>
    std::ostream& operator<<( std::ostream& os,const format_tuple<VA_ARGS...> & ft ) 
    {
      // original implementation
    }

这是一个大纲,因为我不确定如何使用可变参数模板完成它,尽管它应该是可能的.您可以使用1,2,3等参数轻松实现多个版本,例如:

template<typename T1,typename T2,typename T3>
    class format_tuple_3; //etc


    template<typename T1,typename T3>
    format_tuple_3<T1,T2,T3> makeFormatTuple( tuple<T1,T3> const&); //etc

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...