我有一组模板/函数允许我打印一个元组/对,假设元组/对中的每个类型都有运算符<<为它定义.不幸的是,由于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