Subject: Re: [Boost-bugs] [Boost C++ Libraries] #7364: ambiguity error constructing std::vector from assign::list_of
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2012-09-19 15:35:27
#7364: ambiguity error constructing std::vector from assign::list_of
--------------------------------------+-------------------------------------
Reporter: eric_niebler | Owner: nesotto
Type: Bugs | Status: new
Milestone: To Be Determined | Component: assign
Version: Boost Development Trunk | Severity: Problem
Resolution: | Keywords:
--------------------------------------+-------------------------------------
Comment (by eric_niebler):
Below is an implementation of `list_of` that addresses the issue for C++11
compilers.
{{{
#include <iostream>
#include <iterator>
#include <algorithm>
#include <deque>
#include <vector>
#include <utility>
#include <type_traits>
template<typename T>
using uncvref = typename std::remove_cv<typename
std::remove_reference<T>::type>::type;
template<typename T>
struct generic_list;
template<typename T>
generic_list<uncvref<T>> list_of(T && t);
template<typename T>
struct generic_list
{
private:
std::deque<T> values;
friend generic_list<T> list_of<>(T && t);
friend generic_list<T> list_of<>(T & t);
friend generic_list<T> list_of<>(T const & t);
generic_list() = default;
public:
generic_list(generic_list &&) = default;
generic_list(generic_list const &) = delete;
generic_list &operator=(generic_list &&) = delete;
generic_list &operator=(generic_list const &) = delete;
template<typename U>
generic_list & operator()(U && t)
noexcept(noexcept(values.push_back(static_cast<U &&>(t))))
{
values.push_back(static_cast<U &&>(t));
return *this;
}
template<typename Container, typename =
decltype(Container(std::make_move_iterator(values.begin()),
std::make_move_iterator(values.end())))>
operator Container()
noexcept(noexcept(Container(Container(std::make_move_iterator(values.begin()),
std::make_move_iterator(values.end())))))
{
return Container(std::make_move_iterator(values.begin()),
std::make_move_iterator(values.end()));
}
};
template<typename T>
inline generic_list<uncvref<T>> list_of(T && t)
{
return std::move(generic_list<uncvref<T>>()(static_cast<T &&>(t)));
}
struct moveable
{
moveable() = default;
moveable(moveable &&) = default;
moveable(moveable const &) = delete;
moveable &operator=(moveable &&) = default;
moveable &operator=(moveable const &) = delete;
};
int main()
{
std::vector<int> i(list_of(1));
std::copy(i.begin(), i.end(), std::ostream_iterator<int>(std::cout,
"\n"));
std::vector<moveable> j = list_of(moveable())(moveable());
}
}}}
The trick to fixing the ambiguity error is the defaulted template
parameter on `operator Container` that only allows the conversion if the
container can be constructed from a pair of iterators.
HTH.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/7364#comment:2> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:10 UTC