0
#include <iostream>

/**** I am confused to apply sfinae method here ******/

template <typename T>
struct hasTypeFoo {

//..    
static constexpr bool value = true;

};

/////////////////////////////////////////////////

struct A {

    using Foo = int;

};

struct B {


};
int main()
{

    constexpr bool b1 = hasTypeFoo<A>::value;
    constexpr bool b2 = hasTypeFoo<B>::value;

    std::cout << b1 << b2;
}
mai brick
  • 25
  • 6

2 Answers2

3

Use std::void_t:

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

template<typename T>
struct hasTypeFoo<T, std::void_t<typename T::Foo>> : std::true_type { };

A very good explanation of how std::void_t works, can be found in this question. It is used here to silently reject the specialization if typename T::Foo is ill-formed.

Evg
  • 25,259
  • 5
  • 41
  • 83
2

You can do it with partial specialization. e.g.

// primary template
template <typename T, typename = void>
struct hasTypeFoo {
    static constexpr bool value = false;
};

// partial specialization for types containing type Foo    
template <typename T>
struct hasTypeFoo<T, std::void_t<typename T::Foo>> {
    static constexpr bool value = true;
};

LIVE

songyuanyao
  • 169,198
  • 16
  • 310
  • 405