編集:は私の質問への短い答えは、私がSFINAEは何ができるかの誤表示を持っていたし、それがすべてで関数本体をチェックしないということである。does sfinae instantiates a function body?関数が存在し、コンパイル時に使用できるかどうかを検出する方法はありますか?
私はこれと同じ問題を持っている:Is it possible to write a template to check for a function's existence?
違いは、機能が存在するかどうかだけでなく、SFINAEを実際に通過するかどうかを知りたいということです。ここで私が達成しようとしているものの例である:
struct A
{
void FuncA() { std::cout << "A::FuncA" << std::endl; }
};
struct B
{
void FuncA() { std::cout << "B::FuncA" << std::endl; }
void FuncB() { std::cout << "B::FuncB" << std::endl; }
};
template<typename T>
struct Inter
{
void FuncA() { t.FuncA(); }
void FuncB() { t.FuncB(); }
T t;
};
// Always takes some sort of Inter<T>.
template<typename InterType>
struct Final
{
void CallFuncs()
{
// if(t.FuncA() exists and can be called)
t.FuncA();
// if(t.FuncB() exists and can be called)
t.FuncB();
}
InterType t;
};
void DoEverything()
{
Final<Inter<A>> finalA;
Final<Inter<B>> finalB;
finalA.CallFuncs();
finalB.CallFuncs();
}
注意(CallFuncsであること)、FUNCA()とfuncBの()の両方が常に存在しますが、彼らはTが使用するタイプに応じて、コンパイルできませんインターの上記のリンクされた質問で答えを使用しようとしたとき、関数が存在するかどうかをチェックするだけなので、実際にコンパイルすることはできません私ができるどのような方法があるかどう
template<typename InterType>
typename std::enable_if< ! /* how to determine if FuncA can be called? */>::type TryCallFuncA(InterType& i)
{
}
template<typename InterType>
typename std::enable_if</* how to determine if FuncA can be called? */>::type TryCallFuncA(InterType& i)
{
i.FuncA();
}
template<typename InterType>
typename std::enable_if< ! /* how to determine if FuncB can be called? */>::type TryCallFuncB(InterType& i)
{
}
template<typename InterType>
typename std::enable_if</* how to determine if FuncB can be called? */>::type TryCallFuncB(InterType& i)
{
i.FuncB();
}
template<typename InterType>
struct Final
{
void CallFuncs()
{
TryCallFuncA(t);
TryCallFuncB(t);
}
InterType t;
};
が、私はよく分からない。私は条件付きで、私は私のようなenable_if使用することができます理解の関数を呼び出すために
)...アップ何かをネジなかったですenable_ifに渡すブール値を取得します。私はこれを達成する方法がありますか、あるいは機能が存在するかどうかを示す手作業で維持されている何らかの種類の特性に戻す必要がありますか?私の実際の状況では、クラスの実装を重要なメモを追加するには:それは、私が
編集をMSVC 2010を使用している利用可能なC++ 11の機能セット限り価値がある何のため
Inter :: FuncA/FuncBがコンパイルされるかどうかを判断する必要がある時点で、Interは効果的に不透明であるため、子タイプをバブルアップして関数の存在を確認することはできません。
私が正しく覚えていれば、この解決策をC++ 11でのみ利用できるようにするC++ 03のデフォルト引数と関数テンプレートに問題があります。あなたは確認してもらえますか? –
@MatthieuM .:これはC++ 11の解決策です。 C++では、関数テンプレートにデフォルト引数を指定することはできません。これは、新しい標準のレーダーの下で飛んできた本当に素晴らしい機能であり、Xが真でなければ*特定の機能*が過負荷解決に参加しないことを標準が要求している多くの場合に必要です*(つまり、SFINAEは必須です)。 –
残念ながら、それはVS(2010年または2012年)ではサポートされていません。解決策を理解するために、デフォルトの引数&U :: FuncAは存在することだけがチェックされているだけでなく、コンパイルされていると正しくコンパイルされます(例えば、Interに与えられた型自体がテンプレートクラス例えばstruct A )、FuncA/FuncBの実装はそのタイプに依存します)。 –
Screndib