SFINAEに問題があります。私は型に戻り値の型にかかわらず定義されたメンバ関数operator->があるかどうかを判断できる必要があります。例を次に示します。SFINAE - テンプレートの型に '変数'戻り値型のメンバ関数があるかどうかを確認しようとしています
このクラスはテスターにあります。戻り値の型がX *のoperator - >()が定義されています。したがって、どこにいても「X」がどこにハードコードするのか分かりません。
template <class X>
class PointerX
{
...
X* operator->() const;
...
}
このクラスは、渡されたTにメソッドoperator-> definedがあるかどうかを判断しようと試みます。演算子 - >戻り値の型に関係なく。
template<typename T>
struct HasOperatorMemberAccessor
{
template <typename R, typename C> static R GetReturnType(R (C::*)()const);
template<typename U, typename R, R(U::*)()const> struct SFINAE{};
template<typename U> static char Test(SFINAE<U, decltype(GetReturnType(&U::operator->)), &U::operator-> >*);
template<typename U> static uint Test(...);
static const bool value = sizeof(Test<T>(0)) == sizeof(char);
};
このクラスはoperator->戻り型が「オブジェクト」でなければならないこと以外は上記と全く同じです。
template<typename T>
struct HasOperatorMemberAccessorOBJECT
{
template <typename R, typename C> static R GetReturnType(R (C::*)()const);
template<typename U, typename R, R(U::*)()const> struct SFINAE{};
template<typename U> static char Test(SFINAE<U, Object*, &U::operator-> >*); // only change is we hardcoded Object as return type.
template<typename U> static uint Test(...);
static const bool value = sizeof(Test<T>(0)) == sizeof(char);
};
結果:
void main()
{
HasOperatorMemberAccessor<PointerX<Object>>::Test<PointerX<Object>>(0); // fails ::value is false; Test => Test(...)
HasOperatorMemberAccessorOBJECT<PointerX<Object>>::Test<PointerX<Object>>(0); // works! ::value is true; Test => Test(SFINAE<>*)
}
HasOperatorMemberAccessorはPointXのメンバ関数 " - >()constオブジェクト演算子" を見つけることができませんでした。 したがって、Testの汎用バージョンTest(...)が使用されます。
ただし、HasOperatorMemberAccessorOBJECTはPointXの "Object operator - >(const)"を検索できました。 したがって、テスト専用バージョンテスト(SFINAE *)が使用されます。
どちらも "Object operator - >()const"メソッドを見つけることができているはずです。 TestのSpecialized Test(SFINAE *)を使用する必要があります。したがって、HasOperatorMemberAccessor :: :: valueは両方に対してtrueになるはずです。
HasOperatorMemberAccessorとHasOperatorMemberAccessorOBJECT間の唯一の違いはHasOperatorMemberAccessorOBJECTオブジェクトにハードコード型名Rを有していることである、
だから、問題は "decltype(GetReturnType(& U :: operator->は))" オブジェクトを返していないことです正しく私は戻り値の型を発見するためにいくつかの異なる許可を試しました。それらは次のようになります:
decltype(GetReturnType(&U::operator->))
typename decltype(GetReturnType(&U::operator->))
decltype(((U*)nullptr)->operator->())
typename decltype(((U*)nullptr)->operator->())
何もありません、なぜですか?私はMSVC++ 10.0を使用しています。
目立つものは、 'PointerX :: operator->'が 'bool * 'ではなく' bool * 'を返すということです。 –
PointerXのXのタイプは、HasOperatorMemberAccessorに関する限り重要ではありません。この例に多くの無関係のオブジェクトを追加しないことで、私の問題を一般化しようとしました。あまりにも混乱している場合、私はboolを文字列に変更します。 –
私にもう一度お試しください。 'PointerX