メンバー関数でboost :: enable_ifを使用できますか?
質問
テンプレートクラスを書いています。特定のテンプレートタイプに対してのみ追加の方法を存在させることを許可したいと考えています。現在、このメソッドはすべてのテンプレートタイプに存在しますが、他のすべてのタイプにコンパイルエラーが発生します。
これを複雑にすることは、それが過負荷のオペレーター()であるということです。ここで私がやりたいことが実際に可能かどうかはわかりません。
これが私が今持っているものです:
template<typename T, typename BASE>
class MyClass : public BASE
{
public:
typename T& operator() (const Utility1<BASE>& foo);
typename T const& operator() (const Utility2<BASE>& foo) const;
};
私は欲しい T&
バージョンは常に利用可能ですが、 T const&
バージョンはifの場合のみ利用可能です Utility2<BASE>
有効です。現在、両方の方法が存在しますが、constバージョンを使用しようとすると、奇妙なコンパイルエラーが発生します Utility2<BASE>
無効です。賢明なエラー、または「そのようなメンバー関数はない」エラーもありたいです。
これは可能ですか?
編集: :ブーストドキュメントを読んだ後、私が思いついたものは次のとおりです。
template<typename T, typename BASE>
class MyClass : public BASE
{
public:
typename T& operator() (const Utility1<BASE>& foo);
template<typename U>
typename boost::enable_if<boost::is_same<Utility2<BASE>, U>, T>::type const &
operator() (const U& foo) const;
};
そのため、誰かがutility2で使用しようとしない限り、その方法は存在しません。また、そのベースタイプに有効な場合にのみユーティリティ2を作成できます。ただし、そのベースタイプに対して有効でない場合、MyClassはアクセサの方法を作成する時間を無駄にしません。
解決
はい、これは可能ですが、クラステンプレートパラメーターでは直接ではありません。 boost::enable_if
メソッド自体のテンプレートパラメーターでのみ使用できます。したがって、少しtypedef使用法で:
template<typename T, typename BASE>
class MyClass : public BASE
{
public:
typedef Utility2<BASE> util;
typename T& operator() (const Utility1<BASE>& foo);
template<typename U>
typename boost::enable_if<boost::is_same<util, U>, T>::type const &
operator() (const U& foo) const;
};
Utility2は特定のベースタイプからのみ作成できるため、これは機能します。したがって、ベースタイプが別のものである場合、constバージョンのoperator()は存在しません。
だから、それは非常にマイナーなことです。それは私をあまり得ません。しかし、それはすてきでした。