Подтвердить что ты не робот

Может ли static_assert проверить, является ли тип вектором?

Может ли static_assert проверить, является ли тип вектором? IE, a int поднимет это утверждение, тогда как a vector<int> не будет.
Я думаю о чем-то вроде:

static_assert(decltype(T) == std::vector, "Some error")
4b9b3361

Ответ 1

Да. Рассмотрим следующую мета-функцию:

#include <stdio.h>
#include <vector>

template <class N>
struct is_vector { static const int value = 0; };

template <class N, class A>
struct is_vector<std::vector<N, A> > { static const int value = 1; };

int main()
{
   printf("is_vector<int>: %d\n", is_vector<int>::value);
   printf("is_vector<vector<int> >: %d\n", is_vector<std::vector<int> >::value);
}

Просто используйте это как выражение в static_assert.

Ответ 2

С++ 0x:

static_assert(std::is_same<T, std::vector<int>>::value, "Some Error");

Ответ 3

Общее решение. Учитывая тип и шаблон, проверьте, является ли тип экземпляром последнего:

template<typename T, template<typename...> class Tmpl>
struct is_instance_of_a_given_class_template : std:: false_type {};
template<template<typename...> class Tmpl, typename ...Args>
struct is_instance_of_a_given_class_template< Tmpl<Args...>, Tmpl > : std:: true_type {};

При этом будет выполняться следующее:

is_instance_of_a_given_class_template<    vector<int>  ,  vector  > :: value
                    type to check  ~~~~~~~^               ^
        template to check against  ~~~~~~~~~~~~~~~~~~~~~~~/

и, следовательно, вы будете использовать:

static_assert( is_instance_of_a_given_class_template<T,std::vector>::value
              , "Some error")

Примечание. Если T - const, это не будет работать напрямую. Итак, проверьте вместо этого is_instance_of_a_given_class_template< std::decay_t<T> ,std::vector>.

Ответ 4

Да.

template<typename T>
struct isVector
{
  typedef char (&yes)[2];
  template<typename U>
  static yes check(std::vector<U>*);
  static char check(...);

  static const bool value = (sizeof(check((T*)0)) == sizeof(yes));
};

Использование:

isVector<vector<int> >::value;
isVector<int>::value;

Демо.

Примечание. Мой (сложный) ответ имеет ограничение, равное true, если если T публично унаследовано от vector<>. Это может привести к ошибке компилятора, если T имеет private/protected наследование от vector<>. Просто сохраняя это для записи, чтобы этот способ не использовался!:)