10

約 1 週間前に、型に特定のメンバー関数がある場合にのみ、クラス テンプレートを単純にインスタンス化する方法について質問しました。私の答えでは、一種の複雑な解決策を得ました。しかし、それから私は自分でそれをやろうとしました。T特定の型を理解するのに十分なだけの void 関数があるかどうかを知りたかっただけですf0 パラメータを取ります。

#include <type_traits>
#include <utility>

template <typename T, typename = void>
struct has_f : std::false_type { };

template <typename T>
struct has_f<
    T,
    decltype(std::declval<T>().f(), void())> : std::true_type { };

template <typename T, typename = typename std::enable_if<has_f<T>::value>::type>
struct A { };

struct B
{
    void f();
};

struct C { };

template class A<B>; // compiles
template class A<C>; // error: no type named ‘type’ 
                     // in ‘struct std::enable_if<false, void>’

もしそうなら、なぜこのスレッドで他の答えがとても複雑なのですか?

4

1 に答える 1

7

はい、C++11 SFINAE の最も単純で最も慣用的なスタイルで解決しました。

void戻り値の型がであること、非静的メンバーであること、パラメーターがないことを確認していないことに注意してください。f引数なしで簡単に呼び出すことができます。それはファンクターでさえあるかもしれません。

を返す nullary メンバーの非静的関数をチェックするには、次voidを使用します。

template <typename T>
struct has_f<T, decltype(void( static_cast< void (T::*)( void ) >( &T::f ) )) >
    : std::true_type {};

template <typename T>
struct has_f<T, decltype(void( static_cast< void (T::*)( void ) const >( &T::f ) )) >
    : std::true_type {};
于 2013-06-15T14:17:46.980 に答える