What is wrong with my SFINAE to check std :: map / std :: vector?

I have a simple SFINAE script to distinguish standard containers like std::map :

  template <typename Container> struct HasKeyType : sfinae_test { // (C) template <typename U> static Yes test(typename Container::key_type*); // (A) template <typename U> static No test(...); enum {value = (sizeof(test(null)) == sizeof(Yes))}; // (B) }; 

FROM

  struct sfinae_test { typedef char Yes; typedef long No; static void* const null; }; 

When I create an instance using HasKeyType<std::vector<int> >::value , I get

 (A) error: no type named 'key_type' in 'class std::vector<int>' (B) error: invalid use of incomplete type 'struct HasKeyType<std::vector<int> >' (C) error: declaration of 'struct HasKeyType<std::vector<int> >' 

I am completely at a dead end. Why is HasKeyType incomplete, and why does SFINAE not work?

I get similar errors with (B) and (C) if I create an instance of HasKeyType<std::map<int,float> > , which actually has the key type ( int ).

g ++ version: 4.5.2 (yes, I know this is old)

+4
source share
1 answer

You are not using the U pattern in your test method:

 template <typename Container> struct HasKeyType : sfinae_test { // C template <typename U> static Yes test(typename U::key_type* ); // A template <typename U> static No test(U*); enum {value = (sizeof(test<Container>(0)) == sizeof(Yes))}; // B }; 

Notice that I changed test(null) to test<Container>(0) . If your compiler supports it (well, gcc 4.5 is not ...), you can use nullptr instead of 0 .

+4
source

Source: https://habr.com/ru/post/1415832/


All Articles