std容器的type_traits?

时间:2014-06-18 11:53:08

标签: c++ templates c++11 typetraits static-assert

我查看了std::type_traits的列表,但我没有看到有关std容器的任何内容。

我希望验证在编译时将std容器传递给模板类型。

template < typename T >
void foo( T bar )
{
    static_assert( is_std_container??? );
}

2 个答案:

答案 0 :(得分:5)

它不存在。

如果您知道应该支持的容器类型集,则可以创建自己的特征:

template<class T>
struct is_container
{
    static const bool value = false;
};

template<>
template<class T, class Alloc>
struct is_container<std::vector<T, Alloc>>
{
    static const bool value = true; 
};

// ... same specializations for other containers.

你像其他特征一样使用它:

cout << is_container<std::vector<int>>::value << endl;
cout << is_container<int>::value << endl;

here

请注意,通常您应该将迭代器传递给函数,而不是容器。因此,您可以保持代码容器独立且更通用。

答案 1 :(得分:3)

正如其他人在评论中所回答的那样,没有标准的方法可以做到这一点。但是,您可以定义自己的特征系统,以确定类型是否为std容器,如下例所示:

#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <deque>
#include <unordered_set>
#include <unordered_map>
#include <type_traits>

template <typename T> struct container_traits {
  static bool const value = false;  
};

template <typename... Args>
struct container_traits<std::vector<Args...>> {
  static bool const value = true;
};

template <typename... Args>
struct container_traits<std::deque<Args...>> {
  static bool const value = true;
};

template <typename... Args>
struct container_traits<std::list<Args...>> {
  static bool const value = true;
};

template <typename... Args>
struct container_traits<std::set<Args...>> {
  static bool const value = true;
};

template <typename... Args>
struct container_traits<std::map<Args...>> {
  static bool const value = true;
};

template <typename... Args>
struct container_traits<std::unordered_set<Args...>> {
  static bool const value = true;
};

template <typename... Args>
struct container_traits<std::unordered_map<Args...>> {
  static bool const value = true;
};

template<typename T>
struct is_std {
    static constexpr bool const value = container_traits<T>::value;
};

auto main() -> int {
  std::vector<int> v;
  std::cout << std::boolalpha << is_std<decltype(v)>::value << std::endl;
  std::deque<int> dq;
  std::cout << std::boolalpha << is_std<decltype(dq)>::value << std::endl;
  std::set<int> s;
  std::cout << std::boolalpha << is_std<decltype(s)>::value << std::endl;
  std::map<int, int> m;
  std::cout << std::boolalpha << is_std<decltype(m)>::value << std::endl;
  std::unordered_set<int> us;
  std::cout << std::boolalpha << is_std<decltype(us)>::value << std::endl;
  std::unordered_map<int, int> um;
  std::cout << std::boolalpha << is_std<decltype(um)>::value << std::endl;
  std::list<int> l;
  std::cout << std::boolalpha << is_std<decltype(l)>::value << std::endl;
  int i;
  std::cout << std::boolalpha << is_std<decltype(i)>::value << std::endl;
  double d;
  std::cout << std::boolalpha << is_std<decltype(d)>::value << std::endl;

  return 0;
}

DEMO