T_Anton_T
T_Anton_T

Reputation: 21

Creating tuple with allocator c++

I'm learing tuples in C++ and for now I'm trying to create tuple using allocator from libcxx

template <class _Alloc>
LIBCPP_INLINE_VISIBILITY
tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)

for instance:

std::allocator<int> myAllocator;
std::tuple<int> t(std::allocator_arg, myAllocator, 2);

but seems string above called

template <class Alloc>
tuple(allocator_arg_t, const Alloc& a, const Types&...);

what should I change for this?

As well, there is one row that isn't clear for me:

 explicit
 tuple(_Up&&... __u)

how does this call?

Upvotes: 0

Views: 896

Answers (1)

Caleth
Caleth

Reputation: 62719

When you look into your implementation's source and see

namespace std {

    // Other things
    
    template <typename ... _Tp>
    class tuple {
    
        // More things
        
        template <class _Alloc>
        LIBCPP_INLINE_VISIBILITY
        tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
        // an implementation of this constructor
    
    };
}

That is the constructor that cppreference names

template <class Alloc>
tuple(allocator_arg_t, const Alloc& a, const Types&...);

Your implementation has chosen to use names that are reserved for its use. What exactly those names are doesn't matter to the compiler.

what const _Tp& ... __t is?

It's a parameter pack of elements to copy into the tuple. For std::tuple<int>, it is const int&, for std::tuple<std::string, bool, char> it is const std::string &, const bool &, const char &. __t is the name of the parameter pack. C++ allows templates to have different numbers of parameters.

what about tuple(_Up&&... __u)?

That's overload (3)

Converting constructor. Initializes each element of the tuple with the corresponding value in std::forward<UTypes>(args).

This overload only participates in overload resolution if sizeof...(Types) == sizeof...(UTypes) and sizeof...(Types) >= 1 and std::is_constructible<Ti, Ui&&>::value is true for all i.

The constructor is explicit if and only if std::is_convertible<Ui&&, Ti>::value is false for at least one i.

E.g. for std::tuple<int> tup('a');, tup would be initialised by matching UTypes... with char, and the first member would have the numeric value of 'a' (97 on most platforms).

Note that there isn't much point in using an allocator-aware constructor for std::tuple<int>, because int is not a allocator-aware type. Those constructors exist for cases like

using statefully_allocated = std::vector<int, my_stateful_allocator<int>>;
my_stateful_allocator<int> alloc1 = /* something */
statefully_allocated source(alloc);
my_stateful_allocator<int> alloc2 = /* something else */
std::tuple<statefully_allocated, char> tup(std::allocator_arg, alloc2, source, 'a');

Where the statefully_allocated member copies the contents of source, but uses a copy of alloc2 to allocate. the char member is just an ordinary char, alloc2 plays no part in it's construction. See Uses-allocator construction

Upvotes: 2

Related Questions