5

この質問に答えようとしている間、型が多形である(またはそうでない)という事実に基づいてメソッドのオーバーロードを許可するために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が不要な過負荷の無効化を処理すると思いました。

ダミーの2番目の引数の...代わりに(省略記号)を使用してパッチを適用しました...しかし、コンパイラがこれをチョークする理由にはまだ興味があります。disable_if

4

2 に答える 2

11

::type末尾のenable_ifandを忘れたため、コンパイラがチョークしましたdisable_if。テンプレートは常に定義されています。式が(for ) または(for )typeの場合にのみメンバーが存在するというだけです。trueenable_iffalsedisable_if

template <class T>
void* address_of(T* p,
                 typename boost::enable_if< boost::is_polymorphic<T> >::type* dummy = 0)
{ return dynamic_cast<void*>(p); }

template <class T>
void* address_of(T* p,
                 typename boost::disable_if< boost::is_polymorphic<T> >::type* dummy = 0)
{ return static_cast<void*>(p); }

末尾に がない場合、関数テンプレートは、またはの::typeインスタンスへのポインターを2 番目のパラメーターとして受け取るオーバーロードを作成するだけです。末尾に がある場合、テンプレートは type の 2 番目のパラメーターでオーバーロードを作成するか、オーバーロードが削除されます (つまり、望ましい動作)。enable_ifdisable_if::typevoid*

于 2010-08-16T10:07:58.023 に答える
0

enable_if の「戻り型」バージョンを使用すると、3.4.4 で動作します。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;
}
于 2010-08-16T09:23:31.710 に答える