コンパイル時に適切なオーバーロードされた関数テンプレートを選択する方法を理解しようとしていますが、コンパイラが苦労しています。動作させることはできますが、何が起こっているのかわかりません。説明させてください。
以下のような2つの構造体AとBがあります。1 つは特別な機能を持ち、もう 1 つは通常の機能を持っています。
struct A
{
void special() { std::cout << "special called.\n"; }
};
struct B
{
void normal() { std::cout << "normal called.\n"; }
};
私の意図は、特別な関数が利用可能かどうかに応じて、コンパイル時に適切なオーバーロードされた関数テンプレートを選択するメカニズムを持つことです。構造体をパラメーターとして受け取る 2 つの関数を実行して、適切な関数を呼び出すことができるようにします。
template<class Func, Func f> struct Sfinae {};
template <typename U>
static void run(U& u, Sfinae<void (U::*)(), &U::special>* = 0)
{
u.special();
}
template <typename U>
static void run(U& u, ...)
{
u.normal();
}
これを次のようにテストしましたが、さまざまな結果が得られました。
int main()
{
A a;
run<A>(a, 0); // works
run<A>(a); // ERROR: ambiguous overloaded function
run(a, 0); // ERROR: A has no member normal
run(a); // ERROR: ambiguous overloaded function
B b;
run<B>(b, 0); // works
run<B>(b); // works
run(b, 0); // works
run(b); // works
return 0;
}
run(a)
余分な引数や <> なしで使用したいと思います。これが機能しない場合、コードに何か問題がありますか?
また、ここで何が起こっているのか、なぜこれがこのようなことを推測しているのかを理解したいと思って<A>
いA
ますB
。標準が何を言っているのか、これがコンパイラ間で異なるのかどうかはわかりませんが、少なくともLinuxではgcc4.4.4、Macではgcc 4.0.1が説明したように機能します。
誰かがこれに光を当てることができますか?ありがとう!