Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do std::tuple and std::pair support aggregate initialization?

Aggregate initialization requires among other things no user-provided constructors. But std::tuple and std::pair pair have a large set of overloaded constructors. From the point of the core language, are these constructors user-provided or even user-declared ?

With C++17 it will be possible to write (update/clarification: where nocopy is a class that can not be copied or moved, such as std::mutex)

auto get_ensured_rvo_str(){
   return std::pair(std::string(),nocopy());
}

edit: no, it's not possible as explained in the linked to answers and the answer below.

which requires aggregate initialization (for context: Multiple return values (structured bindings) with unmovable types and guaranteed RVO in C++17).

Are tuple and pair backed by special standard language to allow this (in presence of constructors) ? :

20.5.2.1 Construction

... EXPLICIT constexpr tuple(const Types&...);

6 Effects: The constructor initializes each element with the value of the corresponding parameter.

or can we in principle write our own tuple or pair?

like image 499
Johan Lundberg Avatar asked Jul 15 '16 09:07

Johan Lundberg


People also ask

How do you initialize STD tuple?

Initializing a std::tuple We can initialize a std::tuple by passing elements as arguments in constructor i.e. std::tuple<int, double, std::string> result1 { 22, 19.28, "text" }; // Creating and Initializing a tuple std::tuple<int, double, std::string> result1 { 22, 19.28, "text" };

Is std :: pair a tuple?

A tuple is an object capable to hold a collection of elements where each element can be of a different type. The class template needs the header <tuple> . std::tuple is a generalization of std::pair. You can convert between tuples with two elements and pairs.

Is tuple a Constexpr?

Initializes each element of the tuple with the corresponding element of other . This constructor is constexpr if every operation it performs is constexpr. For the empty tuple std::tuple<>, it is constexpr.

Do std::tuple and std::pair support aggregate initialization?

Do std::tuple and std::pair support aggregate initialization? Aggregate initialization requires among other things no user-provided constructors. But std::tuple and std::pair pair have a large set of overloaded constructors. From the point of the core language, are these constructors user-provided or even user-declared ?

How to initialize a std::pair in C++?

This post will discuss how to initialize a std::pair in C++. 1. Initialization Constructor A simple solution to create a std::pair is using its initialization constructor, which takes two arguments corresponding to the first and second member of the pair respectively. 2. Using std::make_pair

How to initialize a pair in C++?

This post will discuss how to initialize a std::pair in C++. 1. Initialization Constructor A simple solution to create a std::pair is using its initialization constructor, which takes two arguments corresponding to the first and second member of the pair respectively.

Are the overloaded constructors in tuple and pair pair user-provided?

Aggregate initialization requires among other things no user-provided constructors. But std::tuple and std::pair pair have a large set of overloaded constructors. From the point of the core language, are these constructors user-provided or even user-declared ?


1 Answers

No, there is no support in tuple or pair for passing no-move types to their constructors, and as you've observed there cannot be, since the constructor argument and tuple (or pair) member can be observed to be different objects:

// exposition only
template<class... Us>
tuple(Us&&... us) : values{std::forward<Us>(us)...} {}
              ^^ these
                    ^^^^^^ are different objects to these

You would have to use piecewise construction:

return std::pair<std::string, nocopy>(std::piecewise_construct,
    std::forward_as_tuple(), std::forward_as_tuple());

Matt Calabrese made an interesting point on the std-proposals list that now we have guaranteed RVO it should be possible to write components that accept factories to construct their members effectively inplace:

// hypothetical factory constructor
return std::pair(std::factory_construct,
    [] { return std::string{}; }, [] { return nocopy{}; });

Another possible direction would be to remove the constructors from tuple and pair (or, more realistically, to write workalike components without constructors) and rely on the new extensions to aggregate initialization that should permit aggregate initialization of tuple and pair implemented via multiple-inheritance. Example.

like image 50
ecatmur Avatar answered Nov 14 '22 15:11

ecatmur