2

ファイルパスを取るコンストラクターを持つすべてのクラスがあります。main 関数の argv 引数から std::tuple を作成したいと思います。ここにスケッチがあります

class A { 
  public:
  A(const char *); // Taking a file path
};

class B {
  public:
  B(const char *); // Taking a file path
};

int main(int argc, char* argv[]) {
  auto tup(myCreateTuple<A, B, A>(argc, argv)); 
  // myCreateTuple would in this case use argv[1], argv[2]
  // and argv[3] to create A(argv[1]), B(argv[2]) and A(argv[3]). 
  // argc is just passed along to verify that argv is long enough.
  // tup would have of the type std::tuple<A ,B, A>
}

タプル メンバーが作成される順序は重要ではありません (つまり、コンストラクタの実行順序は未定義にすることができます)。myCreateTuple を実装する方法についてのアイデアはありますか?

myCreateTuple をまとめて回避し、代わりに使用することは可能だと思います

std::tuple<A, B, A> tup{ A(argv[1]), B(argv[2]), A(argv[3]) };

しかし、それはあまり一般的な解決策ではありません。

4

2 に答える 2

3

を使用<redi/index_tuple.h>して、パック展開で配列インデックスを生成するコンパイル時の整数シーケンスを提供します。

#include <tuple>
#include <assert.h>
#include <redi/index_tuple.h>

template<typename... T, unsigned... I>
inline std::tuple<T...>
myCreateTuple_impl(char** argv, redi::index_tuple<I...>)
{
  return std::tuple<T...>(argv[I+1]...);
}

template<typename... T>
inline std::tuple<T...>
myCreateTuple(int argc, char** argv)
{
  assert(argc > sizeof...(T));
  return myCreateTuple_impl<T...>(argv, redi::to_index_tuple<T...>());
}
于 2012-12-30T12:07:49.883 に答える
1

渡した型の数から、値 1 2 3 (または 0 1 2) の int のコンパイル時シーケンスを作成します。

次に、配列へのインデックスとしてのシーケンスと、... 構文を使用してタプルへのセッターの両方を参照します。または、配列を逆参照する int シーケンスを使用して、コンストラクター呼び出しに ... を直接配置します。

于 2012-12-30T11:47:00.350 に答える