I have template overloads for operator>>() where I need to distinguish between containers that can be resized, e.g., vector, and containers that cannot, e.g., array. I am currently just using the presence of an allocator_type trait (see code, below)--and it works just fine--but was wondering if there is a more explicit way of testing this.
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;
}
				
                        
Thanks to help from @Jarod42 on a separate question, I have a solution that works with C++98, C++03, and C++11; g++ and VS2015. Also, for the problem child,
std::vector<bool>.This is how it's used, below. Notice that both the
has_resize_1andhas_resize_2member-function signatures forresize()are checked. That's because before C++11,resize()had a single signature with two parameters, the last with a default value; as of C++11, it has two signatures--one with one parameter and the other with two parameters. Moreover, VS2015 apparently has three signatures--all of the above. The solution is just to check for both signatures all the time.There is probably a way to combine the two checks into a single type trait, such as
has_resize<C>::value. Tell me if you know.