Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do tuples have uses_allocator but pairs don't?

While experimenting with the C++11 std::scoped_allocator_adaptor as implemented in gcc 4.7.0 so far, I noticed that C++11 FDIS defines a specialization of std::uses_allocator for tuples (20.4.2.8[tuple.traits]), but not for pairs, although for all other purposes, pairs look and act just like tuples (they have specializations of std::get, std::tuple_size, etc).

On further reading, N2554, which introduced these things, defined allocator_arg constructors and uses_allocator specialization for the pairs as well (pages 23-24).

Why were they dropped for pairs? Is there another way to use them that I can't see, or is this a hint of deprecation of pairs in favor of tuples?

My test code was:

// myalloc is like std::allocator, but has a single-argument
// constructor that takes an int, and has NO default constructor
typedef std::vector<int, myalloc<int>> innervector_t;
typedef std::tuple<int, innervector_t> elem_t;
typedef std::scoped_allocator_adaptor<myalloc<elem_t>, myalloc<int>> Alloc;
Alloc a(1,2);
std::vector<elem_t, Alloc> v(a);
v.resize(1);                  // uses allocator #1 for elements of v
// the following line fails to compile if pair is used instead of tuple
// because it attempts to default-construct myalloc<int> for innervector_t
std::get<1>(v[0]).resize(10); // uses allocator #2 for elements of innervector_t
like image 216
Cubbi Avatar asked Aug 31 '11 21:08

Cubbi


1 Answers

One reason is that we want to avoid having 15 constructors (like in N3000) for a seemingly simple class like std::pair.

We have now instead got one "general-purpose" constructor

template <class... Args1, class... Args2>
pair(piecewise_construct_t,
     tuple<Args1...> first_args, tuple<Args2...> second_args);

where you can pass just about anything you like to the constructors of each pair member, including allocators.

like image 57
Bo Persson Avatar answered Jan 04 '23 03:01

Bo Persson