私は静的ポリモーフィズムで少し遊んでいます。初期引数の型に応じて「正しい」特殊な関数を内部的に呼び出す関数を呼び出しています (基本的にタグ付けを行っています)。コードは次のとおりです。
#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_type1
かmy_type2
、内部的tag_type
に適切なタグtag1
/で typedef する必要がありますtag2
。この internal に応じてtag_type
、「正しい」ラッパーが呼び出され、この決定はもちろんコンパイル時に行われます。このコードが機能している理由が本当にわかりませんか? を前方宣言する必要がないのはなぜf_helper
ですか? main
私は最初に の前(および後)にラッパーを定義しましたが、わかりませんがf
、これは理にかなっています。タイプなので、インスタンス化の時点でコンパイラーは.f(type1);
main()
T
f_wrapper
しかしご覧のとおり、ラッパーを AFTER として宣言してもmain()
、コードは機能します。なぜこうなった?コードが機能する理由を尋ねる質問は少し奇妙だと思います:)
編集
コードは、gcc5 および gcc HEAD 6.0.0 でも引き続きコンパイルされます。