У меня есть перегрузки шаблонов для operator>>()
, где мне нужно различать контейнеры, которые могут быть изменены, например vector
, и контейнеры, которые не могут, например, array
. В настоящее время я просто использую признак allocator_type
(см. Код ниже) - и он отлично работает, но задавался вопросом, есть ли более явный способ тестирования этого.Есть ли лучший способ отличить изменяемые размеры контейнеров, чем наличие allocator_type?
template <class T>
struct is_resizable {
typedef uint8_t yes;
typedef uint16_t no;
template <class U>
static yes test(class U::allocator_type *);
template <class U>
static no test(...);
static const bool value = sizeof test<T>(0) == sizeof yes;
};
template <typename C>
typename boost::enable_if_c<
boost::spirit::traits::is_container<C>::value && is_resizable<C>::value,
istream &
>::type
operator>>(istream &ibs, C &c)
{
c.resize(ibs.repeat() == 0 ? c.size() : ibs.repeat());
for (typename C::iterator it = c.begin(); it != c.end(); ++it)
{
C::value_type v;
ibs >> v;
*it = v;
}
return ibs;
}
template <typename C>
typename boost::enable_if_c<
boost::spirit::traits::is_container<C>::value && !is_resizable<C>::value,
istream &
>::type
operator>>(istream &ibs, C &c)
{
for (typename C::iterator it = c.begin(); it != c.end(); ++it)
ibs >> *it;
return ibs;
}
Это не сработает; нет никакой гарантии, что подпись 'resize' на самом деле' void (size_t) '. – Mehrdad
@Mehrdad, это, вероятно, достаточно близко для моих нужд. – plong
@ user4438540: Я сомневаюсь, что этого достаточно ... по крайней мере, вы хотите проверить на 'void (size_t, T)' тоже. – Mehrdad