c ++容器内容特征混乱

时间:2015-04-10 13:09:40

标签: c++ templates traits

我希望能够根据容器类的内容类型选择一个不同的类来在编译时实例化。 Clang和GCC都给出了下面代码的错误,所以我希望它有问题,即使它使用Visual Studio正常运行。有什么想法吗?

#include <iostream>

template <bool, class T = void>
struct enable_if {};

template <class T>
struct enable_if<true, T> {
  typedef T type;
};

struct a {};
struct b {};

struct a_container {
  typedef a contents_type;
};

struct b_container {
  typedef b contents_type;
};

template <class T>
struct is_an_a { enum { value = false }; };

template <>
struct is_an_a<a> { enum { value = true }; };

template <class container_type>
struct container_traits {
  typedef typename container_type::contents_type value_type;
};

template <class container_type>
struct is_an_a_container {
  enum { value = typename is_an_a<typename container_traits<container_type>::value_type>::value };
};

template<class container_type, class enable = void>
struct S {
  void operator()() {
    std::cout << "Not an A\n";
  }
};

template<class container_type>
struct S<container_type, typename enable_if<is_an_a_container<container_type>::value>::type> {
  void operator()() {
    std::cout << "Got an A\n";
  }
};


int main() {
  S<a_container>()();
  S<b_container>()();

  return 0;
}

在Visual Studio中,输出为:

Got an A
Not an A

GCC失败了:

35: error: expected `(' before '}' token

虽然Clang失败了:

35 : error: expected '(' for function-style cast or type construction

我可以通过将is_an_a_container的定义内联到S的第二个版本(例如下面)来解决问题,但在我看来有点模糊,我想了解错误。

template<class container_type>
struct S<container_type, typename enable_if<is_an_a<typename container_traits<container_type>::value_type>::value>::type> {
  void operator()() {
    std::cout << "Got an A\n";
  }
}; 

或者可能有更简洁的解决方案来实现目标?注意:我必须使用container_traits

1 个答案:

答案 0 :(得分:3)

template <class container_type>
struct is_an_a_container {
  enum { value = typename is_an_a<typename conntainer_traits<container_type>::value_type>::value };
                 ^^^^^^^^                                                                  ^^^^^ // this is not a type
};

只需删除typename

即可
template <class container_type>
struct is_an_a_container {
  enum { value = is_an_a<typename conntainer_traits<container_type>::value_type>::value };

};