4

boostmpl変換ドキュメントの次のコードを参照してください。

typedef vector<char,short,int,long,float,double> types;
typedef vector<char*,short*,int*,long*,float*,double*> pointers;
typedef transform< types,boost::add_pointer<_1> >::type result;
BOOST_STATIC_ASSERT(( equal<result,pointers>::value ));

boost::mpl型システムと「実際にどのように機能するか」を理解したい。私が理解mpl::equalしているように、シーケンスタイプ全体ではなく、次の2つのシーケンスの要素を比較するだけです。次のことが失敗する理由がわかりません。

BOOST_STATIC_ASSERT(( std::is_same<result,pointers>::value )); //< assert fails

結果タイプが「ポインタ」タイプと100%同一ではないのはなぜですか?mplが変換を怠惰に実行しているため、または結果が単なるシーケンスであり、ベクトルではなくなったためだと思いますか?どういうわけか、mplを怠惰にせず、100%同一の型を取得することは可能ですか(この結果を使用して自分で変換関数を作成できますが、mplでそれを行う方法を知りたいです)?

たとえば、結果を新しいベクトルに挿入するなど、すでにいくつかのことを試しましたが、成功しませんでした。

BOOST_STATIC_ASSERT(( std::is_same<
  mpl::insert_range< mpl::vector<>, mpl::begin<mpl::vector<> >::type,
  result >::type, pointers >::value )); //< assert fails too

また、変換関数でback_insertを使用しようとしましたが、これも失敗します。

typedef transform< types,boost::add_pointer<_1>,
  mpl::back_inserter< mpl::vector< > > >::type result_new;
BOOST_STATIC_ASSERT(( std::is_same<result_new,pointers>::value )); //< fails...

「ドキュメント」を読んでも役に立ちませんでした。繰り返しになりますが、mpl変換(または他の変換シーケンス関数)で100%同一の型を取得することは可能ですか?そして、タイプの結果は何ですか

result

「実際には」それがポインタと同じでない場合は?

4

1 に答える 1

7

typeid()を使用して型をきれいに出力するコードを提供してくれた@llonesmizに再度感謝します。これは、何が起こっているのかを理解するのに役立ちました。

したがって、実際の結果タイプはコンパイラー(おそらくブースト#ifdefs)に依存しているようで、インテルコンパイラーとビジュアルスタジオはそれをstd :: vectorN <>に変換し直します。ここで、最大Nはブーストで事前定義された数値です(したがって、 Nが大きすぎます)。g ++の場合、マングルされたタイプが生成されます(私のトランスフォーム呼び出しからの2つの異なるタイプでさえ)。

したがって、mpl :: equalを介してタイプをチェックすることは問題ないと思います(範囲の要素をチェックしてください)。すべての型が「本当に」同等である必要がある場合(std :: is_sameが成り立つ)、結果を可変個引数テンプレートクラスstd::tupleに手動で変換する必要があると思います。

http://liveworkspace.org/code/3l8O9K$16コードサンプルを参照してください

または要するに:

template < class T, class R >
struct ToStdTuple;

template < class... TTypes, class X >
struct ToStdTuple< std::tuple< TTypes... >, X >
{
  typedef std::tuple< TTypes..., X > type;
};

その後

// typedef mpl::vector<char,short,int,long,float,double> types;
// typedef mpl::transform< types,boost::add_pointer<mpl::_1> >::type result;

typedef mpl::fold< result, std::tuple<>,
  ToStdTuple< mpl::_1, mpl::_2 > >::type result_normalized;

その結果

std::tuple<char*, short*, int*, long*, float*, double*>

すべての変換呼び出し

于 2013-02-25T18:45:13.337 に答える