4

I have a simple SFINAE scenario to distinuish 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)
 };

With

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

When I instantiate this with 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'm completely stumped at this. Why is HasKeyType incomplete, and why doesn't SFINAE work?

I get similar errors to (B) and (C) as well if I instantiate HasKeyType<std::map<int,float> > which in fact has a key type (int).

g++ version: 4.5.2 (yes, I know it's old)

4

1 に答える 1

4

Uメソッドでテンプレートを使用していませんtest:

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
};

test(null)を aに変更したことに注意してくださいtest<Container>(0)。コンパイラがそれをサポートしている場合 (まあ、gcc 4.5 はサポートしていません...)、nullptr代わりに0.

于 2012-06-03T16:12:27.510 に答える