15

私は静的ポリモーフィズムで少し遊んでいます。初期引数の型に応じて「正しい」特殊な関数を内部的に呼び出す関数を呼び出しています (基本的にタグ付けを行っています)。コードは次のとおりです。

#include <iostream>

using namespace std;

// tags
struct tag1{}; 
struct tag2{}; 

// the compliant types, all should typedef tag_type
struct my_type1
{
    using tag_type = tag1;
};
struct my_type2
{
    using tag_type = tag2;
};

// static dispatch via tagging
template <typename T>
void f(T) 
{
    cout << "In void f<typename T>(T)" << endl;

    // why can I call f_helper without forward definition?!?        
    f_helper(typename T::tag_type{}); 
}

int main()
{
    my_type1 type1;
    my_type2 type2;

    // how does f below knows about f_helper ?!?!
    // even after instantiation f_helper shouldn't be visible!

    f(type1); 
    f(type2);
}

// helper functions
void f_helper(tag1) 
{
    cout << "f called with my_type1" << endl;
}
void f_helper(tag2)
{
    cout << "f called with my_type2" << endl;
}

そのためf(T)、パラメータで呼び出されるmy_type1my_type2、内部的tag_typeに適切なタグtag1/で typedef する必要がありますtag2。この internal に応じてtag_type、「正しい」ラッパーが呼び出され、この決定はもちろんコンパイル時に行われます。このコードが機能している理由が本当にわかりませんか? を前方宣言する必要がないのはなぜf_helperですか? main私は最初に の前(および後)にラッパーを定義しましたが、わかりませんがf、これは理にかなっています。タイプなので、インスタンス化の時点でコンパイラーは.f(type1);main()Tf_wrapper

しかしご覧のとおり、ラッパーを AFTER として宣言してもmain()、コードは機能します。なぜこうなった?コードが機能する理由を尋ねる質問は少し奇妙だと思います:)


編集

コードは、gcc5 および gcc HEAD 6.0.0 でも引き続きコンパイルされます。

4

3 に答える 3