I noticed many a times that whenever one needs to assign values to a (new)std::pair
, std::make_pair
is used. But I did not find any use of the make_pair
function, since we can directly input values to a pair, and modify them as we like.
For example:
std::pair<int,int> newp;
std::cin>>newp.first>>newp.second;
newp.first = -1;
Then what exactly is the use of this function?
std::make_pair
is used to create a std::pair
object with the specified values.
Creates a std::pair object, deducing the target type from the types of arguments.
As a template function which supports automatic template argument type deducing, it allows you omit specifying the target template argument type. e.g.,
auto p1 = std::make_pair(1, 2); // p1 is std::pair<int, int> with value {1, 2}
There is, its advantage is called Template argument deduction. It saves a bit of typing and lets you use auto
. class-template arguments must be explicitly specified, functions, mustn't.
But it becomes redundant with C++17, because we will have Template Argument Deduction For class-templates
we can directly input values to a pair, and modify them as we like. For example:
std::pair<int,int> newp; std::cin>>newp.first>>newp.second; newp.first = -1;
Some problems I can think of:
You don't always have a stream object ready. std::cin
is a very special case, and std::make_pair
is a very generic function.
Who says that both types in the pair support operator>>
?
Const correctness. You may want to have a const
pair.
Let's put these three things together to create a non-compiling example:
#include <utility>
#include <iostream>
struct Foo
{
int i;
};
struct Bar
{
double d;
};
void printPair(std::pair<Foo, Bar> const& pair)
{
std::cout << pair.first.i << " " << pair.second.d << "\n";
}
void createAndPrintPairTwice(Foo const& foo, Bar const& bar)
{
// error 1: no std::cin, need to use foo and bar
// error 2: no operator>> for Foo or Bar
// error 3: cannot change pair values after initialisation
std::pair<Foo, Bar> const newp;
std::cin >> newp.first >> newp.second;
printPair(newp);
printPair(newp);
}
int main()
{
Foo foo;
foo.i = 1;
Bar bar;
bar.d = 1.5;
createAndPrintPairTwice(foo, bar);
}
std::make_pair
solves all three problems and makes the code much nicer to read. Note that you don't have to repeat the pair's template arguments:
void createAndPrintPairTwice(Foo const& foo, Bar const& bar)
{
std::pair<Foo, Bar> const pair = std::make_pair(foo, bar);
printPair(pair);
printPair(pair);
}
What's true is that C++11 has rendered std::make_pair
much less useful than before, because you can now also write:
void createAndPrintPairTwice(Foo const& foo, Bar const& bar)
{
auto const pair = std::pair<Foo, Bar> { foo, bar };
printPair(pair);
printPair(pair);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With