どこかで他の質問に答えて、私はこのコードを書きました。
struct no_type{};
template<typename T> struct has_apply {
static decltype(T().apply<0u>(double())) func( T* ptr );
static no_type func( ... );
static const bool result = !std::is_same<no_type, decltype(func(nullptr))>::value;
};
class A {
public:
template< unsigned n >
void apply( const double& );
};
class B {
};
int main()
{
std::cout << std::boolalpha << has_apply< A >::result << '\n';
std::cout << std::boolalpha << has_apply< B >::result << '\n';
std::cin.get();
return( 0 );
}
Tが、二重右辺値とテンプレートパラメータリテラルを受け入れる非静的メンバー関数 "apply"を提供する場合、結果はtrueである必要があり、それ以外の場合はfalseであるように思われます。ただし、与えられた例は、コンパイル時にクラスBのコンパイルに実際に失敗しますhas_apply<B>
。decltypeステートメントでTの置換が失敗したという事実は、それが単に他の関数を呼び出すことを意味するのではないでしょうか?そういうSFINAEのポイントじゃないですか?
これまでで最もばかげた、無意味な方法で解決しました:
struct no_type{};
template<typename T> struct has_apply {
template<typename U> static decltype(U().apply<0u>(double())) func( U* );
template<typename U> static no_type func( ... );
static const bool result = !std::is_same<no_type, decltype(func<T>(nullptr))>::value;
};
class A {
public:
template< unsigned n >
void apply( const double& );
};
class B {
};
int main()
{
std::cout << std::boolalpha << has_apply< A >::result << '\n';
std::cout << std::boolalpha << has_apply< B >::result << '\n';
std::cin.get();
return( 0 );
}