重複の可能性:
Pretty-print std::tuple
データベース ライブラリ (soci) には、std::tuple<>
1 ~ 10 個のパラメーターで動作する以下のコードのチャンクがあります。
静的クラス メソッドfrom_base()
でありto_base()
、1 タプルから 10 タプルの引数に対して実装されます。
ガッツは基本的に、渡されたストリームとの間ですべての n タプル要素をストリーミングします。すべてがハードコードされています。
代わりに C++11 の可変個引数テンプレートを使用するようにこのコードを変換するにはどうすればよいですか (パラメーターに制限はありません)。 実際に可変長テンプレートを使用するかどうかは二次的なものです。私たちが本当にやりたいことは、ハードコーディングを n タプル引数の一般的なケースに置き換えることです。
問題の一部は、技術的には引数が 1 つしかないことですが、その引数は n タプルであるため、ウィキペディアで説明されている内容を完全に使用することはできません。最善のアプローチは何ですか?
#include "values.h"
#include "type-conversion-traits.h"
#include <tuple>
namespace soci
{
template <typename T0>
struct type_conversion<std::tuple<T0> >
{
typedef values base_type;
static void from_base(base_type const & in, indicator ind,
std::tuple<T0> & out)
{
in
>> std::get<0>(out);
}
static void to_base(std::tuple<T0> & in,
base_type & out, indicator & ind)
{
out
<< std::get<0>(in);
}
};
template <typename T0, typename T1>
struct type_conversion<std::tuple<T0, T1> >
{
typedef values base_type;
static void from_base(base_type const & in, indicator ind,
std::tuple<T0, T1> & out)
{
in
>> std::get<0>(out)
>> std::get<1>(out);
}
static void to_base(std::tuple<T0, T1> & in,
base_type & out, indicator & ind)
{
out
<< std::get<0>(in)
<< std::get<1>(in);
}
};
// ... all the way up to 10 template parameters
}
RUNNABLE ANSWER(以下のGrizzlyの投稿に基づく)
#include <iostream>
#include <tuple>
using namespace std;
// -----------------------------------------------------------------------------
template<unsigned N, unsigned End>
struct to_base_impl
{
template<typename Tuple>
static void execute(Tuple& in, ostream& out)
{
out << std::get<N>(in) << endl;
to_base_impl<N+1, End>::execute(in, out);
}
};
template<unsigned End>
struct to_base_impl<End, End>
{
template<typename Tuple>
static void execute(Tuple& in, ostream& out)
{
out << "<GAME OVER>" << endl;
}
};
// -----------------------------------------------------------------------------
template <typename Tuple>
struct type_conversion
{
static void to_base(Tuple& in, ostream& out )
{
to_base_impl<0, std::tuple_size<Tuple>::value>::execute(in, out);
}
};
template <typename... Args>
struct type_conversion<std::tuple<Args...>>
{
static void to_base(std::tuple<Args...>& in, ostream& out )
{
to_base_impl<0, sizeof...(Args)>::execute(in, out);
}
};
// -----------------------------------------------------------------------------
main()
{
typedef tuple<double,int,string> my_tuple_type;
my_tuple_type t { 2.5, 5, "foo" };
type_conversion<my_tuple_type>::to_base( t, cerr );
}