5

Boost.MPLタイプのシーケンス(リストまたはベクトル)の生成を自動化する次のコードについて考えてみます。

    #include <iostream>                     // cout
    #include <boost/mpl/for_each.hpp>       // for_each
    #include <boost/mpl/identity.hpp>       // identity, make_identity
    #include <boost/mpl/int.hpp>            // int_
    #include <boost/mpl/list.hpp>           // list
    #include <boost/mpl/next.hpp>           // next
    #include <boost/mpl/push_front.hpp>     // push_front
    #include <boost/mpl/vector.hpp>         // vector

    template<size_t, typename> struct iota_n;

    template<typename Value>
    struct iota_n<0, Value>
    :
            boost::mpl::list<>      // can change this to boost::mpl::vector<>
    {};

    template<size_t N, typename Value>
    struct iota_n
    :
            boost::mpl::push_front< typename
                    iota_n< 
                            N - 1, typename
                            boost::mpl::next<Value>::type
                    >::type,
                    Value
            >
    {};

    // works for N <=  20 and boost::mpl::vector
    // works for N <= 247 and boost::mpl::list
    typedef iota_n< 247, boost::mpl::int_<0> >::type sequence;

    struct print
    {
            template<typename T>
            void operator()(boost::mpl::identity<T>)
            {
                    std::cout << T::value << "\n";
            }
    };

    int main()
    {
            boost::mpl::for_each<sequence, boost::mpl::make_identity<> >(
                    print()
            );
            std::cout << BOOST_MPL_LIMIT_LIST_SIZE << '\n';         // 20 on my system
            std::cout << BOOST_MPL_LIMIT_VECTOR_SIZE << '\n';       // 20 on my system
            return 0;
    }

Boost.MPLのドキュメントによると、boost::mpl::listシーケンスには最大で要素を含めることができ、コンパイラの場合BOOST_MPL_LIMIT_LIST_SIZEも同様に最大で。私のシステムでは、両方のマクロが20と評価されます。boost::mpl::vectorBOOST_MPL_LIMIT_VECTOR_SIZE

MSVC ++2010およびBoost1.47.0は、実際、文書化された20要素を超えるベクトルを生成することはできません。ただし、最大247個の要素を含むリストを生成できるのは驚くべきことです。

なぜこれが起こるのか誰かが知っていますか?

4

1 に答える 1

5

ドキュメントに従ってBOOST_MPL_LIMIT_xxx_SIZE、シーケンスの可変個引数形式の制限を指定します(例list<>)。番号付きの形式(例list42<>)には、テンプレートパラメータの数に関するコンパイラの制限を除いて、事前定義された上限はありません。さて、後者のステートメントは完全に正確ではありません。実際には、デフォルトのライブラリ構成で、事前に生成された前処理されたヘッダーを使用することによって課される番号付きフォームに制限があります。それを持ち上げる方法については、この投稿を参照してください。

フォローアップ:@rhalbersmaあなたは2つの別々の概念を束ねているようです:リスト要素の最大数とlistの「コンストラクター」の最大アリティ。前者ではなくBOOST_MPL_LIMIT_LIST_SIZE 後者を制御し、実際には2つの間に依存関係はありません。上記のコードは前者をテストしています。最大テンプレートアリティはまったく異なる獣です。

そもそもMPLシーケンスにアリティ制限がある理由は、ライブラリが可変個引数テンプレート(C ++ 11より前に作成されたもの)をエミュレートする必要があったためです。これは通常、未使用の引数をデフォルトで補助型に設定し、実際のシーケンスを構築する前に、これらの未使用の引数を取り除くための一連の特殊化。これの代償は、デフォルトの引数が通常エラーメッセージに表示され、他のすべてを不明瞭にすることです。また、多数の特殊化がコンパイル時間に顕著な影響を及ぼします。IOW、どこかで停止する必要がありました。当時、20を超えるシーケンス要素をシーケンスの「コンストラクター」に渡す必要があるとは思われませんでした(そうした場合は、常に番号付きのフォームがあります)。したがって、現在の制限。

于 2012-03-01T06:49:25.827 に答える