3

私は次のことが同じ結果をもたらすと期待していました:

namespace mpl = boost::mpl;

template<int from, int to>
struct
make_vector1
 : mpl::copy<
     mpl::range_c<int,from,to>, 
     mpl::inserter< 
       mpl::vector<>,
       mpl::push_back<mpl::placeholders::_1,
              mpl::placeholders::_2 // <- Copy int_ types
             >
       > 
     >  
{};

template<int from, int to>
struct
make_vector2 
 : mpl::copy<
     mpl::range_c<int,from,to>, 
     mpl::inserter< 
       mpl::vector<>,
       mpl::push_back<mpl::placeholders::_1,
              mpl::int_<mpl::placeholders::_2::value> // <- Alternative?
              >
       > 
     >
{};

しかし、そうではありません。

int
main  (int ac, char **av)
{
  typedef make_vector1<0,3>::type v1;
  typedef make_vector2<0,3>::type v2;

  //returns 0, as I would expect
  std::cout<<"I1 = "<<mpl::at<v1,mpl::int_<0> >::type::value <<std::endl;

  //returns 2, which has me stumpted.
  std::cout<<"I2 = "<<mpl::at<v2,mpl::int_<0> >::type::value <<std::endl;
}

ここで何が起こっているのか分かりますか?

Example2番目の方法を使用して、タイプのmpl :: vectorを作成します。ここで、

template<int i>
struct Example : mpl::int_<i>
{};

しかし、私はそれを機能させることができません。

どうもありがとう

4

1 に答える 1

4

_2 の ::value が 2 (プレースホルダー インデックス) に定義されているため、2 が返されます。MPL は明らかな理由でプレースホルダーに :: を定義していないため、これを直接行うことはできません。

ここで、mpl::range_c 内の要素にアクセスすると、お気づきのように既に mpl::int_ が返されているため、数値を抽出して元に戻す必要はありません。mpl シーケンスに対する反復の抽象化がそれを行います。

実際に使用する場合は、mpl::int_ を取得して例を返すメタ関数を使用できます。適切な一般的なメタプログラミングもメタラムダ関数も整数型では実行できないことを把握する必要があるため、 mpl::int_ 抽象化:

#include <boost/mpl/at.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/push_back.hpp>

namespace mpl = boost::mpl;

template<int I> struct Example : boost::mpl::int_<I> 
{
  static void foo() { std::cout << "**" << I << "**\n";}
};

template<class T> struct make_example
{
  typedef Example<T::value> type;
};

template<int from, int to>
struct
make_vector2 
 : mpl::copy<
     mpl::range_c<int,from,to>, 
     mpl::inserter< 
       mpl::vector<>,
       mpl::push_back<mpl::placeholders::_1,
              make_example<mpl::placeholders::_2> // <- Alternative?
              >
       > 
     >
{};

int main(int ac, char **av)
{
  typedef make_vector2<0,3>::type v2;

  mpl::at<v2,mpl::int_<0> >::type::foo();
}

at を呼び出した後に適切なクラス型に移行することを評価するためだけに foo() を追加しました。

それでは、要約しましょう:

  • 統合テンプレート パラメータは危険であり、MPL が int_ を使用するのはそのためです。すべての整数定数シーケンスは、抽象化のレベルを維持するために、実際には既に int_ を返します。
  • プレースホルダーには内部目的の ::value があるため、最初の結果
  • メタ関数は、プレースホルダーを使用してインスタンス化することでラムダに変換できます。
于 2011-06-17T12:44:30.643 に答える