enable_if + disable_ifの組み合わせは、あいまいな呼び出しを引き起こします
質問
答えようとしている間 この質問 の使用を提案したかった enable_if
+ disable_if
タイプが多型であった(またはそうでない)という事実に基づいてメソッドの過負荷を許可する。
そこで、小さなテストファイルを作成しました。
template <class T>
void* address_of(T* p,
boost::enable_if< boost::is_polymorphic<T> >* dummy = 0)
{ return dynamic_cast<void*>(p); }
template <class T>
void* address_of(T* p,
boost::disable_if< boost::is_polymorphic<T> >* dummy = 0)
{ return static_cast<void*>(p); }
struct N { int x; };
int main(int argc, char* argv[])
{
N n;
std::cout << address_of(&n) << std::endl;
return 0;
}
それはかなり飼いならされたようです。
ただし、GCC(3.4 ...)はこれについて窒息します:
test.cpp:機能
int main(int, char**)
:
test.cpp:29:エラー:過負荷の呼び出しaddress_of(N*)
あいまいです
test.cpp:17:注:候補者は次のとおりです。void* address_of(T*, boost::enable_if<boost::is_polymorphic<T>, void>*)
t = nで
test.cpp:20:注:void* address_of(T*, boost::disable_if<boost::is_polymorphic<T>, void>*)
t = nで
ここでどの過負荷を使用すべきかは、私の人間の心にかなり明確に思えます。私は別の代替を定義したことが明らかであり、一度に1つの関数のみを使用できることは明らかです...そして、Sfinaeが不必要な過負荷を無効にすることに注意を払うと思っていたでしょう。
使用してパッチを当てました ...
(Ellipsis)の代わりに disable_if
そして、ダミーの2番目の議論が必要です...しかし、私はまだコンパイラがこれを窒息させる理由に興味があります。
解決
コンパイラは、あなたがトレイルを忘れたので窒息しました ::type
の上 enable_if
と disable_if
. 。 The templates are always defined; it is just that the member type
式がある場合にのみ存在します true
(にとって enable_if
) また false
(にとって disable_if
).
template <class T>
void* address_of(T* p,
TypeName boost::enable_if< boost::is_polymorphic<T> >::タイプ* dummy = 0)
{ return dynamic_cast<void*>(p); }
template <class T>
void* address_of(T* p,
TypeName boost::disable_if< boost::is_polymorphic<T> >::タイプ* dummy = 0)
{ return static_cast<void*>(p); }
トレーリングなし ::type
, 、あなたの関数テンプレートは、のポインターをのインスタンスにかけるオーバーロードを作成するだけです enable_if
また disable_if
2番目のパラメーターとして。トレーリングで ::type
, 、テンプレートは、タイプの2番目のパラメーターで過負荷を作成するかのいずれか void*
, 、または過負荷が削除されます(つまり、目的の動作)。
他のヒント
3.4.4でenable_ifの「リターンタイプ」バージョンを使用してください: gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <iostream>
template <class T>
typename boost::enable_if< boost::is_polymorphic<T>, void* >::type
address_of(T* p)
{ return dynamic_cast<void*>(p); }
template <class T>
typename boost::disable_if< boost::is_polymorphic<T>, void* >::type
address_of(T* p)
{ return static_cast<void*>(p); }
struct N { int x; };
int main(int argc, char* argv[])
{
N n;
std::cout << address_of(&n) << std::endl;
return 0;
}