I can’t understand why such a union of two objects of different or of the same type into one object?
And how is this different from map?
Answer 1, authority 100%
Well, you never know why you might need it. For example, for the same std :: map
: when you iterate over it, the current element is a pair of key and value, that is, respectively std :: pair & lt; K , V & gt;
.
With the help of a couple, it is easy to model a function that may or may not return a value.
Example:
template & lt; typename T & gt;
std :: pair & lt; bool, T & gt; parse_string (const std :: wstring & amp; s)
{
std :: wistringstream iss (s);
T t;
bool success =! (iss & gt; & gt; t) .fail ();
return std :: make_pair (success, t);
}
auto r1 = parse_string & lt; int & gt; (L "123");
if (r1.first)
cout & lt; & lt; r.second;
else
cout & lt; & lt; "fail";
Or, for example, a binary search function in a sorted array. In an amicable way, it should return not some of the found indices, but all indices, because elements can be repeated. However, such a function already exists: std :: equal_range
returns exactly std :: pair
from the start and end iterators.
An integer division function should also return a quotient and remainder pair in an amicable way.
Answer 2, authority 50%
std :: map is a container, it is only efficient for a large enough amount of data ~ & gt; 100. It is not very smart to use it for 1-2 values.
Application:
- Store 2D map tile.
- Store X and Y Coordinates.
- Store variable type for void *.
-
If you need a double key index. (name-surname)
std :: map & lt; std :: string, std :: map & lt; std :: string, dossier & gt; & gt; staff; staff ["Al"] ["Jacobson"]. salary = 500,000; // in this case, the search for the key will be performed 1 time, which can have a positive effect on performance std :: map & lt; std :: pair & lt; std :: string, std :: string & gt;, dossier & gt; staff; staff [std :: pair & lt; std :: string, std :: string & gt; ("El", "Jacobson")]. salary = 500000;
-
Helper variable for defining actions (in addition to VladD’s answer).
enum CAR WASH {CAR, CARGO,
HUMANOID};
std :: pair & lt; HANDLING_TYPE, std :: string & gt; object = current_object_on_line ();
if (object.first == LIGHTWEIGHT) {load_program_light (object.second);}
if (object.first == LOAD) {load_program_loader (object.second);}
if (object.first == HUMANOID) {stop_cleaning (); delete_object (object.second);}
Benefits:
comparison :
// for single variables
int X1;
int Y1;
int X2;
int Y2;
if (X1 == X2 & amp; & amp; Y1 == Y2) {} // doesn't look very good
// for pair
typedef std :: pair & lt; int, int & gt; cell;
cell cell_1;
cell cell_2;
if (cell_1 == cell_2) {} // this is more understandable
Compactness :
If two variables are logically related, then creating a new type (struct) for this relationship is too expensive.
struct product
{
int id;
std :: string name;
operator == ()
operator! = ()
constructor()
};
simpler:
std :: pair & lt; int, std :: string & gt; product;
Speed :
std :: pair & lt; int, std :: string & gt; product;
auto product_id = product.id; // access immediately
std :: map & lt; int, std :: string & gt; product2;
auto product_id = product2.begin () - & gt; first; // access via iterator
Memory :
std :: map allocates memory for different
internal constructions (auxiliary variables) (the same as / h
wood (or not quite c / h)). In debug
mode significantly reduces
performance and makes it difficult
debug.
A pair type, in theory, it has only two members. And memory is allocated only for them.
For example:
template & lt; typename first_, typename second_ & gt;
struct pair
{
first_ first;
second_ second;
};
Disadvantages:
Refactoring will be difficult :
If instead of X, Y it turns out that it is necessary to work with X, Y, Z, then it will not be very pleasant.
You will have to write your own type trira . already with 3 elements or make a struct.