operator<<
タプル/ペアの各タイプが定義されていると仮定して、タプル/ペアを出力できるテンプレート/関数のセットがあります。残念ながら、17.4.3.1 により、operator<<
オーバーロードをに追加することは違法std
です。ADL に私の を見つけさせる別の方法はありますoperator<<
か? そうでない場合、オーバーロードをラップすることに実際の害はありますnamespace 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, typename Tuple>
void operator()(Func 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: 関数 'int main()' 内:
test.cpp:69:31: エラー: 'std::ostream' 左辺値を 'std::basic_ostream&&' にバインドできません > /opt/local/include/gcc45/c++ /ostream:579:5: エラー: 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) の引数 1 を初期化しています [with _CharT = char 、_Traits = std::char_traits、_Tp = std::tuple]'