So here's the code:
template<typename, typename, typename = void>
struct has_member_type : false_type {};
template<typename T, typename Member>
struct has_member_type<T, Member, void_t<typename T::Member>> : true_type {};
struct foo { using bar = int; };
int main()
{
std::cout << has_member_type<foo, typename foo::bar>::value;
}
I'm trying to check whether foo
has a bar
type member. It works fine if the implementation doesn't specify the type member's name, but that way the name is hardcoded into the implementation, which doesn't work for me.
The question said to be duplicate doesn't come close to answering my question. As I explained in the paragraph above, it's fine when the type is hardcoded into the implementation, but I can't get it to work when I specify the type from outside (that's the specific problem). The code compiles fine, but produces wrong results.
Your code doesn't work because typename foo::bar
just directly resolves to int
, rather than passing in some construct you can use for SFINAE.
A possible solution is to make an alias template which will tell you what the type of T::bar
is, then pass that into your checker. This is what std::experimental::is_detected
does. Here is a simplified version which is close to what you had already*:
template<typename, template <typename> class, typename = void>
struct is_detected : false_type {};
template<typename T, template <typename> class Op>
struct is_detected<T, Op, void_t<Op<T>>> : true_type {};
Then you write your alias template which you want to detect:
template <typename T> using bar_t = typename T::bar;
And usage looks like this:
is_detected <foo, bar_t>::value
*: I kept the template parameters the same way around as in your sample code so that you can easily compare. Flipping them around so that you can make the operator arguments variadic is better in a more generic context. It would also make it easier to migrate to std::experimental::is_detected
when available for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With