Boost logo

Boost Users :

Subject: [Boost-users] boost::assign::list_of and C++0x
From: Travis Gockel (travis_at_[hidden])
Date: 2011-06-03 00:48:37


I'm moving a fairly large project over to C++0x, since it is about to be
published (crosses fingers) and we need to stay up with the times. In this
project, we use the wonderful boost::assign::list_of to assign collections
(since initializer lists don't exist yet). We are using g++ 4.5.1 and Boost
1.46.1.

When switching to C++0x, bits of code like this break:

    std::vector<int> vec;
    vec = boost::assign::list_of(1)(2)(3);

with the following error:

break_list_of.cpp:7:41: error: ambiguous overload for ‘operator=’ in ‘vec =
((boost::assign_detail::generic_list<int>*)boost::assign::list_of(const T&)
[with T = int]().boost::assign_detail::generic_list<T>::operator() [with T =
int, boost::assign_detail::generic_list<T> =
boost::assign_detail::generic_list<int>,
boost::assign_detail::generic_list<T>::Ty = int](((const
boost::assign_detail::generic_list<int>::Ty&)((const
boost::assign_detail::generic_list<int>::Ty*)(&2)))))->boost::assign_detail::generic_list<T>::operator()
[with T = int, boost::assign_detail::generic_list<T> =
boost::assign_detail::generic_list<int>,
boost::assign_detail::generic_list<T>::Ty = int](((const
boost::assign_detail::generic_list<int>::Ty&)((const
boost::assign_detail::generic_list<int>::Ty*)(&3))))’
/usr/include/c++/4.5/bits/vector.tcc:156:5: note: candidates are:
std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const
std::vector<_Tp, _Alloc>&) [with _Tp = int, _Alloc = std::allocator<int>]
/usr/include/c++/4.5/bits/stl_vector.h:336:7: note:
std::vector<_Tp, _Alloc>& std::vector<_Tp,
_Alloc>::operator=(std::vector<_Tp, _Alloc>&&) [with _Tp = int, _Alloc =
std::allocator<int>, std::vector<_Tp, _Alloc> = std::vector<int>]
/usr/include/c++/4.5/bits/stl_vector.h:357:7: note:
std::vector<_Tp, _Alloc>& std::vector<_Tp,
_Alloc>::operator=(std::initializer_list<_CharT>) [with _Tp = int, _Alloc =
std::allocator<int>, std::vector<_Tp, _Alloc> = std::vector<int>]

The problem is that there are now multiple ways to assign to vectors (and
all the other collection types). Ideally, I would replace all usage of
boost::assign::list_of with C++0x initializer lists, but, alas, I am lazy.
Furthermore, I think I know how to fix this (see example below) and think
the Boost community would benefit from having boost::assign::list_of work in
C++0x and C++.

template <typename T>
struct is_initializer_list : boost::false_type { };

template <typename T>
struct is_initializer_list<std::initializer_list<T> > : boost::true_type {
};

template <typename T>
struct wrapped_type
{
    wrapped_type(const T& val) :
            _val(val)
    { }

    template <typename TOut,
              // use new support for default template arguments in functions

              typename TPhony = typename
boost::disable_if<is_initializer_list<TOut> >::type
>
    operator TOut() const
    {
        return _val;
    }

private:
    T _val;
};

I was wondering if anybody has solved this problem (or a similar one)
already. I would patch it myself, but I only have g++ and clang to test it
on. Also, there is a high probability that my solution is flawed in some
way.

Thanks for the help! And, as always, thanks for the wonderful library.

-- 
- Travis Gockel


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net