Boost logo

Boost :

Subject: [boost] [container] container_detail::pair piecewise constructor
From: László Szécsi (szecsi_at_[hidden])
Date: 2012-11-14 12:53:04


Hi everyone,

boost::container::container_detail::pair's piecewise constructor is
missing, as acknowledged in a comment. This makes
container::flat_map::emplace less useful (perhaps useless) as the
following will not work:

boost::container::flat_multimap<TestKey, TestValue> testMap;

testMap.emplace(boost::container::container_detail::piecewise_construct,
 boost::make_tuple(30),
 boost::make_tuple(50));

where both TestKey and TestValue are non-copyable, moveable classes
with a constructor taking an int.

The compilation error message will correctly say that
boost::container::container_detail::pair does not have a constructor
with three arguments.

I tried to implement the missing piecewise constructor based on
std::pair's in the g++ standard libraries. I failed at it, so I would
like to request some assistance and education. This is where I got:

// from the standard lib
template<std::size_t _Num>
struct _Build_index_tuple
{ typedef typename _Build_index_tuple<_Num-1>::__type::__next __type; };

// from the standard lib
template<>
struct _Build_index_tuple<0>
{ typedef _Index_tuple<> __type; };

template <class... Args1, class... Args2>
pair(piecewise_construct_t, ::boost::tuple<Args1...> first_args,
::boost::tuple<Args2...> second_args)
  : pair(::boost::move(first_args), ::boost::move(second_args),
  typename _Build_index_tuple<sizeof...(Args1)>::__type(),
  typename _Build_index_tuple<sizeof...(Args2)>::__type())
  {}

template<typename... Args1, std::size_t... Indices1, typename...
Args2, std::size_t... Indices2>
explicit pair(tuple<Args1...> tuple1, tuple<Args2...> tuple2,
  _Index_tuple<Indices1...>, _Index_tuple<Indices2...>)
  : first(::boost::forward<Args1>(std::get<Indices1>(tuple1))...),
  second(::boost::forward<Args2>(std::get<Indices2>(tuple2))...)
  { }

This gets me a recursive error message far too long to quote, starting with:
error C2664: 'boost::container::container_detail::pair<Key,T>::pair(std::pair<Key,T>
&&)' : cannot convert parameter 3 from
'boost::tuples::tuple<int,boost::tuples::null_type // lot of
null_types omitted
 to 'boost::tuples::tuple<boost::tuples::null_type, // lot of null_types omitted

I used the VS2012 Nov CTP compiler.

I understand that variadic templates have not been very portable and
boost::unordered, which has a piecewise constructor implementation,
does it completely differently and much more painfully. But is there a
reason for the approach I tried not to work with boost at all?

Could you please help me fix this code?

Thank you very much,
Laszlo Szecsi


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk