3

わかりました。ここで疑似コードを完成させてください。

template <typename T>
void fun(/*...*/)
{
    some_meta_typelist pushback T;
}

つまり、この関数がインスタンス化されると、いつでもsome_meta_typelistオブジェクトが大きくなるという考え方です。これが境界を越えて行われる場合、タイプリストがおそらくMPL :: fold関数で使用される前に、このテンプレート構築メカニズムへのすべての呼び出しがコンパイルされるという保証はありますか?これらはいつ評価され、いつ行われたことを確認できますか?これはコンパイル単位に限定し、.cppの境界を越えないようにする必要がありますか?静的変数を使用して関数を呼び出し、使用前にオブジェクトが作成されていることを確認するのと同じことはありますか?

アップデート

私は、システムを呼び出すオブジェクトが、システムがその作業を行うために必要なタイプリストを作成するという考えを見ています。私の考えでは、タイプリストは完全にコンパイル順序に依存するため、単一ファイルのCPPを超える有効なアプローチではありません。MSVCはアルファベット順でコンパイルされるか、少なくとも以前はコンパイルされていたので、最終ファイルにZZZZ.cppという名前を付けることができます。最終的には、完全にビルドされたタイプリストが必要なファイルを意味します。これは安全または互換性のあるソリューションではありません。これは本当ですか?回避策はありますか?

皆さんありがとう

4

1 に答える 1

4

これは、テンプレートのインスタンス化がどのように機能するかについての単純化された、骨抜きにされたバージョンです(foldのBoostドキュメントを調べます)。

あなたがC++コンパイラであり(あなたを呼びましょうclang...それはかなりクールな名前です)、.cppそれをコンパイルするためにファイルを楽しく読んでいるとしましょう。void foo()、、float magic(int x, double p)などの通常の機能がすべて表示されint main(int argc, char** argv)ます。次に、次のようなものに出くわします。

template <typename T>
struct is_fun
{
    typedef some_other_type<T> something_else;
    typedef typename something_else::value value;
}

ここで、次のように述べています。かっこいい、パラメータとして単一のタイプを持つテンプレートである、clangという名前のこの構造について知っています。is_funこの時点で、is_funは初期化されていないテンプレートです。ここでは何もコンパイルしていないことに注意することが重要です。テンプレート化されたclangものを見ると、構文を(可能な範囲で)チェックして次に進みます。初期化されていないテンプレートをオブジェクトコードで出力する方法はありません。これは純粋にC++であり、コンパイルされていません。

後で、それがやって来て、is_fun次のようなステートメントで使用されるのを確認します。

typedef vector<long,float,short,double,float,long,long double> types;
typedef fold<
             types,
             int_<0>,
             if_< is_fun<_2>,next<_1>,_1 >
            >
        ::type number_of_fun;

さて、clang怠惰で、「さて、number_of_funそれはその恐ろしいものの単なる別名です」とだけ言います。繰り返しますが、それは何もしませ。コードの後半で、次のように表示されます。

int foo()
{
    const int fun = number_of_fun::value;
    return fun;
}

number_of_fun、それはテンプレートで何かをしました。これで、テンプレートパラメータに値が入力されます(使用するには値number_of_fun::valueが必要なため)。 clangすべてのBoostのものをステップスルーし、最終的にはテンプレート化されたものになりますis_fun。リストで最初に必要なのは(ベクトルの折りたたみが行うことです)であるため、すべてのsが入力されlongたlongに基づいて新しい型が作成されます。T

struct is_fun<long>
{
    typedef some_other_type<long> something_else;
    static const int value = typename something_else::value;
}

このタイプ使用されているため、コンパイルされます。C ++テンプレートの基本的なルールは次のとおりです。コンパイル中に使用すると、インスタンス化されます。つまり、コンパイルされます。実行時に行う必要のある特別なことは何もありません。

于 2011-05-01T16:23:57.383 に答える