What is the purpose of std::make_pair vs the constructor of std::pair?Why not infer template parameter from constructor?Why is it better to use std::make_* instead of the constructor?Use of `std::make_pair` in std::pair : C++ STLKeep object and reference to an object created inside a functionWhy does make_pair<int,int> fail in C++ 11?What is the difference between #include <filename> and #include “filename”?Regular cast vs. static_cast vs. dynamic_castWhat are the differences between a pointer variable and a reference variable in C++?What does the explicit keyword mean?Why is “using namespace std;” considered bad practice?What is the “-->” operator in C++?What are rvalues, lvalues, xvalues, glvalues, and prvalues?Easiest way to convert int to string in C++C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?Why is processing a sorted array faster than processing an unsorted array?
Short Story: Cold War setting. In orbit, two astronauts decide whether to launch nuclear counter strike ("MAD" scenario). Twist at end
What exactly happened to the 18 crew members who were reported as "missing" in "Q Who"?
Meaning and structure of headline "Hair it is: A List of ..."
Vegetarian dishes on Russian trains (European part)
Will some rockets really collapse under their own weight?
Physical Interpretation of an Overdamped Pendulum
Build a mob of suspiciously happy lenny faces ( ͡° ͜ʖ ͡°)
Why do we use low resistance cables to minimize power losses?
μονάδαι as plural form of μονάς
What are the advantages of this gold finger shape?
Get the full text of a long request
If a person claims to know anything could it be disproven by saying 'prove that we are not in a simulation'?
What should I do with the stock I own if I anticipate there will be a recession?
What would be synonyms for "be into something"?
What is the opposite of "hunger level"?
Eric Andre had a dream
global variant of csname…endcsname
If I am sleeping clutching on to something, how easy is it to steal that item?
Has there ever been a truly bilingual country prior to the contemporary period?
Animate flow lines of time-dependent 3D dynamical system
Why can't I see 1861 / 1871 census entries on Freecen website when I can see them on Ancestry website?
Are there any cons in using rounded corners for bar graphs?
A Magic Diamond
Do predators tend to have vertical slit pupils versus horizontal for prey animals?
What is the purpose of std::make_pair vs the constructor of std::pair?
Why not infer template parameter from constructor?Why is it better to use std::make_* instead of the constructor?Use of `std::make_pair` in std::pair : C++ STLKeep object and reference to an object created inside a functionWhy does make_pair<int,int> fail in C++ 11?What is the difference between #include <filename> and #include “filename”?Regular cast vs. static_cast vs. dynamic_castWhat are the differences between a pointer variable and a reference variable in C++?What does the explicit keyword mean?Why is “using namespace std;” considered bad practice?What is the “-->” operator in C++?What are rvalues, lvalues, xvalues, glvalues, and prvalues?Easiest way to convert int to string in C++C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?Why is processing a sorted array faster than processing an unsorted array?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
What is the purpose of std::make_pair?
Why not just do std::pair<int, char>(0, 'a')?
Is there any difference between the two methods?
c++ stl std-pair
add a comment |
What is the purpose of std::make_pair?
Why not just do std::pair<int, char>(0, 'a')?
Is there any difference between the two methods?
c++ stl std-pair
5
In C++11, you can almost entirely do without make_pair. See my answer.
– PlagueHammer
Mar 19 '14 at 6:54
2
In C++17,std::make_pairis redundant. There is an answer below that details this.
– Drew Dormann
May 22 '18 at 14:56
add a comment |
What is the purpose of std::make_pair?
Why not just do std::pair<int, char>(0, 'a')?
Is there any difference between the two methods?
c++ stl std-pair
What is the purpose of std::make_pair?
Why not just do std::pair<int, char>(0, 'a')?
Is there any difference between the two methods?
c++ stl std-pair
c++ stl std-pair
edited Jan 6 '17 at 10:35
Ciro Santilli 新疆改造中心996ICU六四事件
166k36 gold badges631 silver badges514 bronze badges
166k36 gold badges631 silver badges514 bronze badges
asked Feb 14 '12 at 1:37
user542687
5
In C++11, you can almost entirely do without make_pair. See my answer.
– PlagueHammer
Mar 19 '14 at 6:54
2
In C++17,std::make_pairis redundant. There is an answer below that details this.
– Drew Dormann
May 22 '18 at 14:56
add a comment |
5
In C++11, you can almost entirely do without make_pair. See my answer.
– PlagueHammer
Mar 19 '14 at 6:54
2
In C++17,std::make_pairis redundant. There is an answer below that details this.
– Drew Dormann
May 22 '18 at 14:56
5
5
In C++11, you can almost entirely do without make_pair. See my answer.
– PlagueHammer
Mar 19 '14 at 6:54
In C++11, you can almost entirely do without make_pair. See my answer.
– PlagueHammer
Mar 19 '14 at 6:54
2
2
In C++17,
std::make_pair is redundant. There is an answer below that details this.– Drew Dormann
May 22 '18 at 14:56
In C++17,
std::make_pair is redundant. There is an answer below that details this.– Drew Dormann
May 22 '18 at 14:56
add a comment |
7 Answers
7
active
oldest
votes
The difference is that with std::pair you need to specify the types of both elements, whereas std::make_pair will create a pair with the type of the elements that are passed to it, without you needing to tell it. That's what I could gather from various docs anyways.
See this example from http://www.cplusplus.com/reference/std/utility/make_pair/
pair <int,int> one;
pair <int,int> two;
one = make_pair (10,20);
two = make_pair (10.5,'A'); // ok: implicit conversion from pair<double,char>
Aside from the implicit conversion bonus of it, if you didn't use make_pair you'd have to do
one = pair<int,int>(10,20)
every time you assigned to one, which would be annoying over time...
Actually, the types should be deduced at compile time without the need to specify.
– Chad
Feb 14 '12 at 1:51
@Tor Yeah, I know how to use both of them, I was just curious if there was a reason forstd::make_pair. Apparently it is just for convenience.
– user542687
Feb 14 '12 at 1:56
@Jay It would appear so.
– Tor Valamo
Feb 14 '12 at 1:58
14
I think you can doone = 10, 20nowadays but I don't have a C++11 compiler handy to check it.
– MSalters
Feb 14 '12 at 8:11
5
Also note thatmake_pairworks with unnamed types, including structs, unions, lambdas, and other doodads.
– Mooing Duck
Feb 6 '15 at 22:29
add a comment |
As @MSalters replied above, you can now use curly braces to do this in C++11 (just verified this with a C++11 compiler):
pair<int, int> p = 1, 2;
add a comment |
There is no difference between using make_pair and explicitly calling the pair constructor with specified type arguments. std::make_pair is more convenient when the types are verbose because a template method has type deduction based on its given parameters.
For example,
std::vector< std::pair< std::vector<int>, std::vector<int> > > vecOfPair;
std::vector<int> emptyV;
// shorter
vecOfPair.push_back(std::make_pair(emptyV, emptyV));
// longer
vecOfPair.push_back(std::pair< std::vector<int>, std::vector<int> >(emptyV, emptyV));
add a comment |
It's worth noting that this is a common idiom in C++ template programming. It's known as the Object Generator idiom, you can find more information and a nice example here.
Edit As someone suggested in the comments (since removed) the following is a slightly modified extract from the link in case it breaks.
An Object Generator allows creation of objects without explicitly specifying their types. It is based on a useful property of function templates which class templates don't have: The type parameters of a function template are deduced automatically from its actual parameters. std::make_pair is a simple example that returns an instance of the std::pair template depending on the actual parameters of the std::make_pair function.
template <class T, class U>
std::pair <T, U>
make_pair(T t, U u)
return std::pair <T, U> (t,u);
1
I think your code is missing references&
– Mooing Duck
Feb 6 '15 at 22:31
1
@duck Actually&&since C++11.
– Justme0
Jan 22 '18 at 15:53
add a comment |
Class template arguments could not be inferred from the constructor before C++17
Before C++17 you could not write something like:
std::pair p(1, 'a');
since that would infer template types from the constructor arguments.
C++17 makes that syntax possible, and therefore make_pair redundant.
Before C++17, std::make_pair allowed us to write less verbose code:
MyLongClassName1 o1();
MyLongClassName2 o2();
auto p = std::make_pair(o1, o2);
instead of the more verbose:
std::pair<MyLongClassName1,MyLongClassName2> po1, o2;
which repeats the types, and can be very long.
Type inference works in that pre-C++17 case because make_pair is not a constructor.
make_pair is essentially equivalent to:
template<class T1, class T2>
std::pair<T1, T2> my_make_pair(T1 t1, T2 t2)
return std::pair<T1, T2>(t1, t2);
The same concept applies to inserter vs insert_iterator.
See also:
- Why not infer template parameter from constructor?
- https://en.wikibooks.org/wiki/More_C++_Idioms/Object_Generator
Minimal example
To make things more concrete, we can observe the problem minimally with:
main.cpp
template <class MyType>
struct MyClass
MyType i;
MyClass(MyType i) : i(i)
;
template<class MyType>
MyClass<MyType> make_my_class(MyType i)
return MyClass<MyType>(i);
int main()
MyClass<int> my_class(1);
then:
g++-8 -Wall -Wextra -Wpedantic -std=c++17 main.cpp
compiles happily, but:
g++-8 -Wall -Wextra -Wpedantic -std=c++14 main.cpp
fails with:
main.cpp: In function ‘int main()’:
main.cpp:13:13: error: missing template arguments before ‘my_class’
MyClass my_class(1);
^~~~~~~~
and requires instead to work:
MyClass<int> my_class(1);
or the helper:
auto my_class = make_my_class(1);
which uses a regular function instead of a constructor.
Tested with GCC 8.1.0, Ubuntu 16.04.
1
"C++17 makes that syntax possible, and therefore make_pair redundant." - Why is it thatstd::make_pairdid not become deprecated in C++17?
– andreee
Nov 6 '18 at 10:23
@andreee I'm not sure, possible reason is that it creates no trouble so no need to break old code? But I'm not familiar with C++ committee rationale, ping me if you find something.
– Ciro Santilli 新疆改造中心996ICU六四事件
Nov 6 '18 at 10:51
1
One useful thing that I have come across is that being able to specify the types with std::make_pair<T1, T2>(o1, o2) prevents the user from making the mistake of passing types o1 or o2 that can't implicitly be cast to T1 or T2. For instance passing a negative number to an unsigned int. -Wsign-conversion -Werror will not catch this error with std::pair constructor in c++11 however it will catch the error if std::make_pair is used.
– conchoecia
Jan 30 at 21:36
add a comment |
make_pair creates an extra copy over the direct constructor. I always typedef my pairs to provide simple syntax.
This shows the difference (example by Rampal Chaudhary):
class Sample
static int _noOfObjects;
int _objectNo;
public:
Sample() :
_objectNo( _noOfObjects++ )
std::cout<<"Inside default constructor of object "<<_objectNo<<std::endl;
Sample( const Sample& sample) :
_objectNo( _noOfObjects++ )
std::cout<<"Inside copy constructor of object "<<_objectNo<<std::endl;
~Sample()
std::cout<<"Destroying object "<<_objectNo<<std::endl;
;
int Sample::_noOfObjects = 0;
int main(int argc, char* argv[])
Sample sample;
std::map<int,Sample> map;
map.insert( std::make_pair( 1, sample) );
//map.insert( std::pair<int,Sample>( 1, sample) );
return 0;
4
I am pretty sure that the extra copy will be elided in all cases, if the optimization settings of the compiler are high enough.
– Björn Pollex
Feb 19 '14 at 13:00
Why would you ever want to rely on compiler optimizations for correctness?
– sjbx
Dec 2 '16 at 8:46
I get the same results with both versions, and withstd::movejust insideinsertand/or around what would be a reference tosample. It is only when I changestd::map<int,Sample>tostd::map<int,Sample const&>that I reduce the number of constructed objects, and only when I delete the copy constructor that I eliminate all copies (obviously). After making both of those changes, my result includes one call to the default constructor and two calls to the destructor for the same object. I think I must be missing something. (g++ 5.4.1, c++11)
– John P
Aug 30 '17 at 23:13
FWIW I agree that optimization and correctness should be completely independent, as this is exactly the kind of code you write as a sanity check after different optimization levels produce inconsistent results. In general I would recommendemplaceinstead ofinsertif you're just constructing a value to insert immediately (and you don't want extra instances.) It's not my area of expertise, if I can even say I have one, but the copy/move semantics introduced by C++11 have helped me a lot.
– John P
Aug 30 '17 at 23:31
add a comment |
starting from c++11 just use uniform initialization for pairs. So instead of:
std::make_pair(1, 2);
or
std::pair<int, int>(1, 2);
just use
1, 2;
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9270563%2fwhat-is-the-purpose-of-stdmake-pair-vs-the-constructor-of-stdpair%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
The difference is that with std::pair you need to specify the types of both elements, whereas std::make_pair will create a pair with the type of the elements that are passed to it, without you needing to tell it. That's what I could gather from various docs anyways.
See this example from http://www.cplusplus.com/reference/std/utility/make_pair/
pair <int,int> one;
pair <int,int> two;
one = make_pair (10,20);
two = make_pair (10.5,'A'); // ok: implicit conversion from pair<double,char>
Aside from the implicit conversion bonus of it, if you didn't use make_pair you'd have to do
one = pair<int,int>(10,20)
every time you assigned to one, which would be annoying over time...
Actually, the types should be deduced at compile time without the need to specify.
– Chad
Feb 14 '12 at 1:51
@Tor Yeah, I know how to use both of them, I was just curious if there was a reason forstd::make_pair. Apparently it is just for convenience.
– user542687
Feb 14 '12 at 1:56
@Jay It would appear so.
– Tor Valamo
Feb 14 '12 at 1:58
14
I think you can doone = 10, 20nowadays but I don't have a C++11 compiler handy to check it.
– MSalters
Feb 14 '12 at 8:11
5
Also note thatmake_pairworks with unnamed types, including structs, unions, lambdas, and other doodads.
– Mooing Duck
Feb 6 '15 at 22:29
add a comment |
The difference is that with std::pair you need to specify the types of both elements, whereas std::make_pair will create a pair with the type of the elements that are passed to it, without you needing to tell it. That's what I could gather from various docs anyways.
See this example from http://www.cplusplus.com/reference/std/utility/make_pair/
pair <int,int> one;
pair <int,int> two;
one = make_pair (10,20);
two = make_pair (10.5,'A'); // ok: implicit conversion from pair<double,char>
Aside from the implicit conversion bonus of it, if you didn't use make_pair you'd have to do
one = pair<int,int>(10,20)
every time you assigned to one, which would be annoying over time...
Actually, the types should be deduced at compile time without the need to specify.
– Chad
Feb 14 '12 at 1:51
@Tor Yeah, I know how to use both of them, I was just curious if there was a reason forstd::make_pair. Apparently it is just for convenience.
– user542687
Feb 14 '12 at 1:56
@Jay It would appear so.
– Tor Valamo
Feb 14 '12 at 1:58
14
I think you can doone = 10, 20nowadays but I don't have a C++11 compiler handy to check it.
– MSalters
Feb 14 '12 at 8:11
5
Also note thatmake_pairworks with unnamed types, including structs, unions, lambdas, and other doodads.
– Mooing Duck
Feb 6 '15 at 22:29
add a comment |
The difference is that with std::pair you need to specify the types of both elements, whereas std::make_pair will create a pair with the type of the elements that are passed to it, without you needing to tell it. That's what I could gather from various docs anyways.
See this example from http://www.cplusplus.com/reference/std/utility/make_pair/
pair <int,int> one;
pair <int,int> two;
one = make_pair (10,20);
two = make_pair (10.5,'A'); // ok: implicit conversion from pair<double,char>
Aside from the implicit conversion bonus of it, if you didn't use make_pair you'd have to do
one = pair<int,int>(10,20)
every time you assigned to one, which would be annoying over time...
The difference is that with std::pair you need to specify the types of both elements, whereas std::make_pair will create a pair with the type of the elements that are passed to it, without you needing to tell it. That's what I could gather from various docs anyways.
See this example from http://www.cplusplus.com/reference/std/utility/make_pair/
pair <int,int> one;
pair <int,int> two;
one = make_pair (10,20);
two = make_pair (10.5,'A'); // ok: implicit conversion from pair<double,char>
Aside from the implicit conversion bonus of it, if you didn't use make_pair you'd have to do
one = pair<int,int>(10,20)
every time you assigned to one, which would be annoying over time...
edited Feb 14 '12 at 1:51
answered Feb 14 '12 at 1:39
Tor ValamoTor Valamo
27.1k10 gold badges66 silver badges76 bronze badges
27.1k10 gold badges66 silver badges76 bronze badges
Actually, the types should be deduced at compile time without the need to specify.
– Chad
Feb 14 '12 at 1:51
@Tor Yeah, I know how to use both of them, I was just curious if there was a reason forstd::make_pair. Apparently it is just for convenience.
– user542687
Feb 14 '12 at 1:56
@Jay It would appear so.
– Tor Valamo
Feb 14 '12 at 1:58
14
I think you can doone = 10, 20nowadays but I don't have a C++11 compiler handy to check it.
– MSalters
Feb 14 '12 at 8:11
5
Also note thatmake_pairworks with unnamed types, including structs, unions, lambdas, and other doodads.
– Mooing Duck
Feb 6 '15 at 22:29
add a comment |
Actually, the types should be deduced at compile time without the need to specify.
– Chad
Feb 14 '12 at 1:51
@Tor Yeah, I know how to use both of them, I was just curious if there was a reason forstd::make_pair. Apparently it is just for convenience.
– user542687
Feb 14 '12 at 1:56
@Jay It would appear so.
– Tor Valamo
Feb 14 '12 at 1:58
14
I think you can doone = 10, 20nowadays but I don't have a C++11 compiler handy to check it.
– MSalters
Feb 14 '12 at 8:11
5
Also note thatmake_pairworks with unnamed types, including structs, unions, lambdas, and other doodads.
– Mooing Duck
Feb 6 '15 at 22:29
Actually, the types should be deduced at compile time without the need to specify.
– Chad
Feb 14 '12 at 1:51
Actually, the types should be deduced at compile time without the need to specify.
– Chad
Feb 14 '12 at 1:51
@Tor Yeah, I know how to use both of them, I was just curious if there was a reason for
std::make_pair. Apparently it is just for convenience.– user542687
Feb 14 '12 at 1:56
@Tor Yeah, I know how to use both of them, I was just curious if there was a reason for
std::make_pair. Apparently it is just for convenience.– user542687
Feb 14 '12 at 1:56
@Jay It would appear so.
– Tor Valamo
Feb 14 '12 at 1:58
@Jay It would appear so.
– Tor Valamo
Feb 14 '12 at 1:58
14
14
I think you can do
one = 10, 20 nowadays but I don't have a C++11 compiler handy to check it.– MSalters
Feb 14 '12 at 8:11
I think you can do
one = 10, 20 nowadays but I don't have a C++11 compiler handy to check it.– MSalters
Feb 14 '12 at 8:11
5
5
Also note that
make_pair works with unnamed types, including structs, unions, lambdas, and other doodads.– Mooing Duck
Feb 6 '15 at 22:29
Also note that
make_pair works with unnamed types, including structs, unions, lambdas, and other doodads.– Mooing Duck
Feb 6 '15 at 22:29
add a comment |
As @MSalters replied above, you can now use curly braces to do this in C++11 (just verified this with a C++11 compiler):
pair<int, int> p = 1, 2;
add a comment |
As @MSalters replied above, you can now use curly braces to do this in C++11 (just verified this with a C++11 compiler):
pair<int, int> p = 1, 2;
add a comment |
As @MSalters replied above, you can now use curly braces to do this in C++11 (just verified this with a C++11 compiler):
pair<int, int> p = 1, 2;
As @MSalters replied above, you can now use curly braces to do this in C++11 (just verified this with a C++11 compiler):
pair<int, int> p = 1, 2;
edited Mar 22 '14 at 21:06
Martin
7,6556 gold badges28 silver badges30 bronze badges
7,6556 gold badges28 silver badges30 bronze badges
answered Feb 24 '14 at 18:28
PlagueHammerPlagueHammer
23k30 gold badges81 silver badges94 bronze badges
23k30 gold badges81 silver badges94 bronze badges
add a comment |
add a comment |
There is no difference between using make_pair and explicitly calling the pair constructor with specified type arguments. std::make_pair is more convenient when the types are verbose because a template method has type deduction based on its given parameters.
For example,
std::vector< std::pair< std::vector<int>, std::vector<int> > > vecOfPair;
std::vector<int> emptyV;
// shorter
vecOfPair.push_back(std::make_pair(emptyV, emptyV));
// longer
vecOfPair.push_back(std::pair< std::vector<int>, std::vector<int> >(emptyV, emptyV));
add a comment |
There is no difference between using make_pair and explicitly calling the pair constructor with specified type arguments. std::make_pair is more convenient when the types are verbose because a template method has type deduction based on its given parameters.
For example,
std::vector< std::pair< std::vector<int>, std::vector<int> > > vecOfPair;
std::vector<int> emptyV;
// shorter
vecOfPair.push_back(std::make_pair(emptyV, emptyV));
// longer
vecOfPair.push_back(std::pair< std::vector<int>, std::vector<int> >(emptyV, emptyV));
add a comment |
There is no difference between using make_pair and explicitly calling the pair constructor with specified type arguments. std::make_pair is more convenient when the types are verbose because a template method has type deduction based on its given parameters.
For example,
std::vector< std::pair< std::vector<int>, std::vector<int> > > vecOfPair;
std::vector<int> emptyV;
// shorter
vecOfPair.push_back(std::make_pair(emptyV, emptyV));
// longer
vecOfPair.push_back(std::pair< std::vector<int>, std::vector<int> >(emptyV, emptyV));
There is no difference between using make_pair and explicitly calling the pair constructor with specified type arguments. std::make_pair is more convenient when the types are verbose because a template method has type deduction based on its given parameters.
For example,
std::vector< std::pair< std::vector<int>, std::vector<int> > > vecOfPair;
std::vector<int> emptyV;
// shorter
vecOfPair.push_back(std::make_pair(emptyV, emptyV));
// longer
vecOfPair.push_back(std::pair< std::vector<int>, std::vector<int> >(emptyV, emptyV));
answered Feb 14 '12 at 1:49
devildevil
1,54414 silver badges22 bronze badges
1,54414 silver badges22 bronze badges
add a comment |
add a comment |
It's worth noting that this is a common idiom in C++ template programming. It's known as the Object Generator idiom, you can find more information and a nice example here.
Edit As someone suggested in the comments (since removed) the following is a slightly modified extract from the link in case it breaks.
An Object Generator allows creation of objects without explicitly specifying their types. It is based on a useful property of function templates which class templates don't have: The type parameters of a function template are deduced automatically from its actual parameters. std::make_pair is a simple example that returns an instance of the std::pair template depending on the actual parameters of the std::make_pair function.
template <class T, class U>
std::pair <T, U>
make_pair(T t, U u)
return std::pair <T, U> (t,u);
1
I think your code is missing references&
– Mooing Duck
Feb 6 '15 at 22:31
1
@duck Actually&&since C++11.
– Justme0
Jan 22 '18 at 15:53
add a comment |
It's worth noting that this is a common idiom in C++ template programming. It's known as the Object Generator idiom, you can find more information and a nice example here.
Edit As someone suggested in the comments (since removed) the following is a slightly modified extract from the link in case it breaks.
An Object Generator allows creation of objects without explicitly specifying their types. It is based on a useful property of function templates which class templates don't have: The type parameters of a function template are deduced automatically from its actual parameters. std::make_pair is a simple example that returns an instance of the std::pair template depending on the actual parameters of the std::make_pair function.
template <class T, class U>
std::pair <T, U>
make_pair(T t, U u)
return std::pair <T, U> (t,u);
1
I think your code is missing references&
– Mooing Duck
Feb 6 '15 at 22:31
1
@duck Actually&&since C++11.
– Justme0
Jan 22 '18 at 15:53
add a comment |
It's worth noting that this is a common idiom in C++ template programming. It's known as the Object Generator idiom, you can find more information and a nice example here.
Edit As someone suggested in the comments (since removed) the following is a slightly modified extract from the link in case it breaks.
An Object Generator allows creation of objects without explicitly specifying their types. It is based on a useful property of function templates which class templates don't have: The type parameters of a function template are deduced automatically from its actual parameters. std::make_pair is a simple example that returns an instance of the std::pair template depending on the actual parameters of the std::make_pair function.
template <class T, class U>
std::pair <T, U>
make_pair(T t, U u)
return std::pair <T, U> (t,u);
It's worth noting that this is a common idiom in C++ template programming. It's known as the Object Generator idiom, you can find more information and a nice example here.
Edit As someone suggested in the comments (since removed) the following is a slightly modified extract from the link in case it breaks.
An Object Generator allows creation of objects without explicitly specifying their types. It is based on a useful property of function templates which class templates don't have: The type parameters of a function template are deduced automatically from its actual parameters. std::make_pair is a simple example that returns an instance of the std::pair template depending on the actual parameters of the std::make_pair function.
template <class T, class U>
std::pair <T, U>
make_pair(T t, U u)
return std::pair <T, U> (t,u);
edited Apr 3 '14 at 9:37
answered Mar 15 '13 at 14:35
mkmmkm
4954 silver badges18 bronze badges
4954 silver badges18 bronze badges
1
I think your code is missing references&
– Mooing Duck
Feb 6 '15 at 22:31
1
@duck Actually&&since C++11.
– Justme0
Jan 22 '18 at 15:53
add a comment |
1
I think your code is missing references&
– Mooing Duck
Feb 6 '15 at 22:31
1
@duck Actually&&since C++11.
– Justme0
Jan 22 '18 at 15:53
1
1
I think your code is missing references
&– Mooing Duck
Feb 6 '15 at 22:31
I think your code is missing references
&– Mooing Duck
Feb 6 '15 at 22:31
1
1
@duck Actually
&& since C++11.– Justme0
Jan 22 '18 at 15:53
@duck Actually
&& since C++11.– Justme0
Jan 22 '18 at 15:53
add a comment |
Class template arguments could not be inferred from the constructor before C++17
Before C++17 you could not write something like:
std::pair p(1, 'a');
since that would infer template types from the constructor arguments.
C++17 makes that syntax possible, and therefore make_pair redundant.
Before C++17, std::make_pair allowed us to write less verbose code:
MyLongClassName1 o1();
MyLongClassName2 o2();
auto p = std::make_pair(o1, o2);
instead of the more verbose:
std::pair<MyLongClassName1,MyLongClassName2> po1, o2;
which repeats the types, and can be very long.
Type inference works in that pre-C++17 case because make_pair is not a constructor.
make_pair is essentially equivalent to:
template<class T1, class T2>
std::pair<T1, T2> my_make_pair(T1 t1, T2 t2)
return std::pair<T1, T2>(t1, t2);
The same concept applies to inserter vs insert_iterator.
See also:
- Why not infer template parameter from constructor?
- https://en.wikibooks.org/wiki/More_C++_Idioms/Object_Generator
Minimal example
To make things more concrete, we can observe the problem minimally with:
main.cpp
template <class MyType>
struct MyClass
MyType i;
MyClass(MyType i) : i(i)
;
template<class MyType>
MyClass<MyType> make_my_class(MyType i)
return MyClass<MyType>(i);
int main()
MyClass<int> my_class(1);
then:
g++-8 -Wall -Wextra -Wpedantic -std=c++17 main.cpp
compiles happily, but:
g++-8 -Wall -Wextra -Wpedantic -std=c++14 main.cpp
fails with:
main.cpp: In function ‘int main()’:
main.cpp:13:13: error: missing template arguments before ‘my_class’
MyClass my_class(1);
^~~~~~~~
and requires instead to work:
MyClass<int> my_class(1);
or the helper:
auto my_class = make_my_class(1);
which uses a regular function instead of a constructor.
Tested with GCC 8.1.0, Ubuntu 16.04.
1
"C++17 makes that syntax possible, and therefore make_pair redundant." - Why is it thatstd::make_pairdid not become deprecated in C++17?
– andreee
Nov 6 '18 at 10:23
@andreee I'm not sure, possible reason is that it creates no trouble so no need to break old code? But I'm not familiar with C++ committee rationale, ping me if you find something.
– Ciro Santilli 新疆改造中心996ICU六四事件
Nov 6 '18 at 10:51
1
One useful thing that I have come across is that being able to specify the types with std::make_pair<T1, T2>(o1, o2) prevents the user from making the mistake of passing types o1 or o2 that can't implicitly be cast to T1 or T2. For instance passing a negative number to an unsigned int. -Wsign-conversion -Werror will not catch this error with std::pair constructor in c++11 however it will catch the error if std::make_pair is used.
– conchoecia
Jan 30 at 21:36
add a comment |
Class template arguments could not be inferred from the constructor before C++17
Before C++17 you could not write something like:
std::pair p(1, 'a');
since that would infer template types from the constructor arguments.
C++17 makes that syntax possible, and therefore make_pair redundant.
Before C++17, std::make_pair allowed us to write less verbose code:
MyLongClassName1 o1();
MyLongClassName2 o2();
auto p = std::make_pair(o1, o2);
instead of the more verbose:
std::pair<MyLongClassName1,MyLongClassName2> po1, o2;
which repeats the types, and can be very long.
Type inference works in that pre-C++17 case because make_pair is not a constructor.
make_pair is essentially equivalent to:
template<class T1, class T2>
std::pair<T1, T2> my_make_pair(T1 t1, T2 t2)
return std::pair<T1, T2>(t1, t2);
The same concept applies to inserter vs insert_iterator.
See also:
- Why not infer template parameter from constructor?
- https://en.wikibooks.org/wiki/More_C++_Idioms/Object_Generator
Minimal example
To make things more concrete, we can observe the problem minimally with:
main.cpp
template <class MyType>
struct MyClass
MyType i;
MyClass(MyType i) : i(i)
;
template<class MyType>
MyClass<MyType> make_my_class(MyType i)
return MyClass<MyType>(i);
int main()
MyClass<int> my_class(1);
then:
g++-8 -Wall -Wextra -Wpedantic -std=c++17 main.cpp
compiles happily, but:
g++-8 -Wall -Wextra -Wpedantic -std=c++14 main.cpp
fails with:
main.cpp: In function ‘int main()’:
main.cpp:13:13: error: missing template arguments before ‘my_class’
MyClass my_class(1);
^~~~~~~~
and requires instead to work:
MyClass<int> my_class(1);
or the helper:
auto my_class = make_my_class(1);
which uses a regular function instead of a constructor.
Tested with GCC 8.1.0, Ubuntu 16.04.
1
"C++17 makes that syntax possible, and therefore make_pair redundant." - Why is it thatstd::make_pairdid not become deprecated in C++17?
– andreee
Nov 6 '18 at 10:23
@andreee I'm not sure, possible reason is that it creates no trouble so no need to break old code? But I'm not familiar with C++ committee rationale, ping me if you find something.
– Ciro Santilli 新疆改造中心996ICU六四事件
Nov 6 '18 at 10:51
1
One useful thing that I have come across is that being able to specify the types with std::make_pair<T1, T2>(o1, o2) prevents the user from making the mistake of passing types o1 or o2 that can't implicitly be cast to T1 or T2. For instance passing a negative number to an unsigned int. -Wsign-conversion -Werror will not catch this error with std::pair constructor in c++11 however it will catch the error if std::make_pair is used.
– conchoecia
Jan 30 at 21:36
add a comment |
Class template arguments could not be inferred from the constructor before C++17
Before C++17 you could not write something like:
std::pair p(1, 'a');
since that would infer template types from the constructor arguments.
C++17 makes that syntax possible, and therefore make_pair redundant.
Before C++17, std::make_pair allowed us to write less verbose code:
MyLongClassName1 o1();
MyLongClassName2 o2();
auto p = std::make_pair(o1, o2);
instead of the more verbose:
std::pair<MyLongClassName1,MyLongClassName2> po1, o2;
which repeats the types, and can be very long.
Type inference works in that pre-C++17 case because make_pair is not a constructor.
make_pair is essentially equivalent to:
template<class T1, class T2>
std::pair<T1, T2> my_make_pair(T1 t1, T2 t2)
return std::pair<T1, T2>(t1, t2);
The same concept applies to inserter vs insert_iterator.
See also:
- Why not infer template parameter from constructor?
- https://en.wikibooks.org/wiki/More_C++_Idioms/Object_Generator
Minimal example
To make things more concrete, we can observe the problem minimally with:
main.cpp
template <class MyType>
struct MyClass
MyType i;
MyClass(MyType i) : i(i)
;
template<class MyType>
MyClass<MyType> make_my_class(MyType i)
return MyClass<MyType>(i);
int main()
MyClass<int> my_class(1);
then:
g++-8 -Wall -Wextra -Wpedantic -std=c++17 main.cpp
compiles happily, but:
g++-8 -Wall -Wextra -Wpedantic -std=c++14 main.cpp
fails with:
main.cpp: In function ‘int main()’:
main.cpp:13:13: error: missing template arguments before ‘my_class’
MyClass my_class(1);
^~~~~~~~
and requires instead to work:
MyClass<int> my_class(1);
or the helper:
auto my_class = make_my_class(1);
which uses a regular function instead of a constructor.
Tested with GCC 8.1.0, Ubuntu 16.04.
Class template arguments could not be inferred from the constructor before C++17
Before C++17 you could not write something like:
std::pair p(1, 'a');
since that would infer template types from the constructor arguments.
C++17 makes that syntax possible, and therefore make_pair redundant.
Before C++17, std::make_pair allowed us to write less verbose code:
MyLongClassName1 o1();
MyLongClassName2 o2();
auto p = std::make_pair(o1, o2);
instead of the more verbose:
std::pair<MyLongClassName1,MyLongClassName2> po1, o2;
which repeats the types, and can be very long.
Type inference works in that pre-C++17 case because make_pair is not a constructor.
make_pair is essentially equivalent to:
template<class T1, class T2>
std::pair<T1, T2> my_make_pair(T1 t1, T2 t2)
return std::pair<T1, T2>(t1, t2);
The same concept applies to inserter vs insert_iterator.
See also:
- Why not infer template parameter from constructor?
- https://en.wikibooks.org/wiki/More_C++_Idioms/Object_Generator
Minimal example
To make things more concrete, we can observe the problem minimally with:
main.cpp
template <class MyType>
struct MyClass
MyType i;
MyClass(MyType i) : i(i)
;
template<class MyType>
MyClass<MyType> make_my_class(MyType i)
return MyClass<MyType>(i);
int main()
MyClass<int> my_class(1);
then:
g++-8 -Wall -Wextra -Wpedantic -std=c++17 main.cpp
compiles happily, but:
g++-8 -Wall -Wextra -Wpedantic -std=c++14 main.cpp
fails with:
main.cpp: In function ‘int main()’:
main.cpp:13:13: error: missing template arguments before ‘my_class’
MyClass my_class(1);
^~~~~~~~
and requires instead to work:
MyClass<int> my_class(1);
or the helper:
auto my_class = make_my_class(1);
which uses a regular function instead of a constructor.
Tested with GCC 8.1.0, Ubuntu 16.04.
edited Mar 27 at 12:58
answered Jan 7 '17 at 12:26
Ciro Santilli 新疆改造中心996ICU六四事件Ciro Santilli 新疆改造中心996ICU六四事件
166k36 gold badges631 silver badges514 bronze badges
166k36 gold badges631 silver badges514 bronze badges
1
"C++17 makes that syntax possible, and therefore make_pair redundant." - Why is it thatstd::make_pairdid not become deprecated in C++17?
– andreee
Nov 6 '18 at 10:23
@andreee I'm not sure, possible reason is that it creates no trouble so no need to break old code? But I'm not familiar with C++ committee rationale, ping me if you find something.
– Ciro Santilli 新疆改造中心996ICU六四事件
Nov 6 '18 at 10:51
1
One useful thing that I have come across is that being able to specify the types with std::make_pair<T1, T2>(o1, o2) prevents the user from making the mistake of passing types o1 or o2 that can't implicitly be cast to T1 or T2. For instance passing a negative number to an unsigned int. -Wsign-conversion -Werror will not catch this error with std::pair constructor in c++11 however it will catch the error if std::make_pair is used.
– conchoecia
Jan 30 at 21:36
add a comment |
1
"C++17 makes that syntax possible, and therefore make_pair redundant." - Why is it thatstd::make_pairdid not become deprecated in C++17?
– andreee
Nov 6 '18 at 10:23
@andreee I'm not sure, possible reason is that it creates no trouble so no need to break old code? But I'm not familiar with C++ committee rationale, ping me if you find something.
– Ciro Santilli 新疆改造中心996ICU六四事件
Nov 6 '18 at 10:51
1
One useful thing that I have come across is that being able to specify the types with std::make_pair<T1, T2>(o1, o2) prevents the user from making the mistake of passing types o1 or o2 that can't implicitly be cast to T1 or T2. For instance passing a negative number to an unsigned int. -Wsign-conversion -Werror will not catch this error with std::pair constructor in c++11 however it will catch the error if std::make_pair is used.
– conchoecia
Jan 30 at 21:36
1
1
"C++17 makes that syntax possible, and therefore make_pair redundant." - Why is it that
std::make_pair did not become deprecated in C++17?– andreee
Nov 6 '18 at 10:23
"C++17 makes that syntax possible, and therefore make_pair redundant." - Why is it that
std::make_pair did not become deprecated in C++17?– andreee
Nov 6 '18 at 10:23
@andreee I'm not sure, possible reason is that it creates no trouble so no need to break old code? But I'm not familiar with C++ committee rationale, ping me if you find something.
– Ciro Santilli 新疆改造中心996ICU六四事件
Nov 6 '18 at 10:51
@andreee I'm not sure, possible reason is that it creates no trouble so no need to break old code? But I'm not familiar with C++ committee rationale, ping me if you find something.
– Ciro Santilli 新疆改造中心996ICU六四事件
Nov 6 '18 at 10:51
1
1
One useful thing that I have come across is that being able to specify the types with std::make_pair<T1, T2>(o1, o2) prevents the user from making the mistake of passing types o1 or o2 that can't implicitly be cast to T1 or T2. For instance passing a negative number to an unsigned int. -Wsign-conversion -Werror will not catch this error with std::pair constructor in c++11 however it will catch the error if std::make_pair is used.
– conchoecia
Jan 30 at 21:36
One useful thing that I have come across is that being able to specify the types with std::make_pair<T1, T2>(o1, o2) prevents the user from making the mistake of passing types o1 or o2 that can't implicitly be cast to T1 or T2. For instance passing a negative number to an unsigned int. -Wsign-conversion -Werror will not catch this error with std::pair constructor in c++11 however it will catch the error if std::make_pair is used.
– conchoecia
Jan 30 at 21:36
add a comment |
make_pair creates an extra copy over the direct constructor. I always typedef my pairs to provide simple syntax.
This shows the difference (example by Rampal Chaudhary):
class Sample
static int _noOfObjects;
int _objectNo;
public:
Sample() :
_objectNo( _noOfObjects++ )
std::cout<<"Inside default constructor of object "<<_objectNo<<std::endl;
Sample( const Sample& sample) :
_objectNo( _noOfObjects++ )
std::cout<<"Inside copy constructor of object "<<_objectNo<<std::endl;
~Sample()
std::cout<<"Destroying object "<<_objectNo<<std::endl;
;
int Sample::_noOfObjects = 0;
int main(int argc, char* argv[])
Sample sample;
std::map<int,Sample> map;
map.insert( std::make_pair( 1, sample) );
//map.insert( std::pair<int,Sample>( 1, sample) );
return 0;
4
I am pretty sure that the extra copy will be elided in all cases, if the optimization settings of the compiler are high enough.
– Björn Pollex
Feb 19 '14 at 13:00
Why would you ever want to rely on compiler optimizations for correctness?
– sjbx
Dec 2 '16 at 8:46
I get the same results with both versions, and withstd::movejust insideinsertand/or around what would be a reference tosample. It is only when I changestd::map<int,Sample>tostd::map<int,Sample const&>that I reduce the number of constructed objects, and only when I delete the copy constructor that I eliminate all copies (obviously). After making both of those changes, my result includes one call to the default constructor and two calls to the destructor for the same object. I think I must be missing something. (g++ 5.4.1, c++11)
– John P
Aug 30 '17 at 23:13
FWIW I agree that optimization and correctness should be completely independent, as this is exactly the kind of code you write as a sanity check after different optimization levels produce inconsistent results. In general I would recommendemplaceinstead ofinsertif you're just constructing a value to insert immediately (and you don't want extra instances.) It's not my area of expertise, if I can even say I have one, but the copy/move semantics introduced by C++11 have helped me a lot.
– John P
Aug 30 '17 at 23:31
add a comment |
make_pair creates an extra copy over the direct constructor. I always typedef my pairs to provide simple syntax.
This shows the difference (example by Rampal Chaudhary):
class Sample
static int _noOfObjects;
int _objectNo;
public:
Sample() :
_objectNo( _noOfObjects++ )
std::cout<<"Inside default constructor of object "<<_objectNo<<std::endl;
Sample( const Sample& sample) :
_objectNo( _noOfObjects++ )
std::cout<<"Inside copy constructor of object "<<_objectNo<<std::endl;
~Sample()
std::cout<<"Destroying object "<<_objectNo<<std::endl;
;
int Sample::_noOfObjects = 0;
int main(int argc, char* argv[])
Sample sample;
std::map<int,Sample> map;
map.insert( std::make_pair( 1, sample) );
//map.insert( std::pair<int,Sample>( 1, sample) );
return 0;
4
I am pretty sure that the extra copy will be elided in all cases, if the optimization settings of the compiler are high enough.
– Björn Pollex
Feb 19 '14 at 13:00
Why would you ever want to rely on compiler optimizations for correctness?
– sjbx
Dec 2 '16 at 8:46
I get the same results with both versions, and withstd::movejust insideinsertand/or around what would be a reference tosample. It is only when I changestd::map<int,Sample>tostd::map<int,Sample const&>that I reduce the number of constructed objects, and only when I delete the copy constructor that I eliminate all copies (obviously). After making both of those changes, my result includes one call to the default constructor and two calls to the destructor for the same object. I think I must be missing something. (g++ 5.4.1, c++11)
– John P
Aug 30 '17 at 23:13
FWIW I agree that optimization and correctness should be completely independent, as this is exactly the kind of code you write as a sanity check after different optimization levels produce inconsistent results. In general I would recommendemplaceinstead ofinsertif you're just constructing a value to insert immediately (and you don't want extra instances.) It's not my area of expertise, if I can even say I have one, but the copy/move semantics introduced by C++11 have helped me a lot.
– John P
Aug 30 '17 at 23:31
add a comment |
make_pair creates an extra copy over the direct constructor. I always typedef my pairs to provide simple syntax.
This shows the difference (example by Rampal Chaudhary):
class Sample
static int _noOfObjects;
int _objectNo;
public:
Sample() :
_objectNo( _noOfObjects++ )
std::cout<<"Inside default constructor of object "<<_objectNo<<std::endl;
Sample( const Sample& sample) :
_objectNo( _noOfObjects++ )
std::cout<<"Inside copy constructor of object "<<_objectNo<<std::endl;
~Sample()
std::cout<<"Destroying object "<<_objectNo<<std::endl;
;
int Sample::_noOfObjects = 0;
int main(int argc, char* argv[])
Sample sample;
std::map<int,Sample> map;
map.insert( std::make_pair( 1, sample) );
//map.insert( std::pair<int,Sample>( 1, sample) );
return 0;
make_pair creates an extra copy over the direct constructor. I always typedef my pairs to provide simple syntax.
This shows the difference (example by Rampal Chaudhary):
class Sample
static int _noOfObjects;
int _objectNo;
public:
Sample() :
_objectNo( _noOfObjects++ )
std::cout<<"Inside default constructor of object "<<_objectNo<<std::endl;
Sample( const Sample& sample) :
_objectNo( _noOfObjects++ )
std::cout<<"Inside copy constructor of object "<<_objectNo<<std::endl;
~Sample()
std::cout<<"Destroying object "<<_objectNo<<std::endl;
;
int Sample::_noOfObjects = 0;
int main(int argc, char* argv[])
Sample sample;
std::map<int,Sample> map;
map.insert( std::make_pair( 1, sample) );
//map.insert( std::pair<int,Sample>( 1, sample) );
return 0;
edited Nov 28 '13 at 14:34
answered Nov 28 '13 at 13:40
EmpZoooliEmpZoooli
412 bronze badges
412 bronze badges
4
I am pretty sure that the extra copy will be elided in all cases, if the optimization settings of the compiler are high enough.
– Björn Pollex
Feb 19 '14 at 13:00
Why would you ever want to rely on compiler optimizations for correctness?
– sjbx
Dec 2 '16 at 8:46
I get the same results with both versions, and withstd::movejust insideinsertand/or around what would be a reference tosample. It is only when I changestd::map<int,Sample>tostd::map<int,Sample const&>that I reduce the number of constructed objects, and only when I delete the copy constructor that I eliminate all copies (obviously). After making both of those changes, my result includes one call to the default constructor and two calls to the destructor for the same object. I think I must be missing something. (g++ 5.4.1, c++11)
– John P
Aug 30 '17 at 23:13
FWIW I agree that optimization and correctness should be completely independent, as this is exactly the kind of code you write as a sanity check after different optimization levels produce inconsistent results. In general I would recommendemplaceinstead ofinsertif you're just constructing a value to insert immediately (and you don't want extra instances.) It's not my area of expertise, if I can even say I have one, but the copy/move semantics introduced by C++11 have helped me a lot.
– John P
Aug 30 '17 at 23:31
add a comment |
4
I am pretty sure that the extra copy will be elided in all cases, if the optimization settings of the compiler are high enough.
– Björn Pollex
Feb 19 '14 at 13:00
Why would you ever want to rely on compiler optimizations for correctness?
– sjbx
Dec 2 '16 at 8:46
I get the same results with both versions, and withstd::movejust insideinsertand/or around what would be a reference tosample. It is only when I changestd::map<int,Sample>tostd::map<int,Sample const&>that I reduce the number of constructed objects, and only when I delete the copy constructor that I eliminate all copies (obviously). After making both of those changes, my result includes one call to the default constructor and two calls to the destructor for the same object. I think I must be missing something. (g++ 5.4.1, c++11)
– John P
Aug 30 '17 at 23:13
FWIW I agree that optimization and correctness should be completely independent, as this is exactly the kind of code you write as a sanity check after different optimization levels produce inconsistent results. In general I would recommendemplaceinstead ofinsertif you're just constructing a value to insert immediately (and you don't want extra instances.) It's not my area of expertise, if I can even say I have one, but the copy/move semantics introduced by C++11 have helped me a lot.
– John P
Aug 30 '17 at 23:31
4
4
I am pretty sure that the extra copy will be elided in all cases, if the optimization settings of the compiler are high enough.
– Björn Pollex
Feb 19 '14 at 13:00
I am pretty sure that the extra copy will be elided in all cases, if the optimization settings of the compiler are high enough.
– Björn Pollex
Feb 19 '14 at 13:00
Why would you ever want to rely on compiler optimizations for correctness?
– sjbx
Dec 2 '16 at 8:46
Why would you ever want to rely on compiler optimizations for correctness?
– sjbx
Dec 2 '16 at 8:46
I get the same results with both versions, and with
std::move just inside insert and/or around what would be a reference to sample. It is only when I change std::map<int,Sample> to std::map<int,Sample const&> that I reduce the number of constructed objects, and only when I delete the copy constructor that I eliminate all copies (obviously). After making both of those changes, my result includes one call to the default constructor and two calls to the destructor for the same object. I think I must be missing something. (g++ 5.4.1, c++11)– John P
Aug 30 '17 at 23:13
I get the same results with both versions, and with
std::move just inside insert and/or around what would be a reference to sample. It is only when I change std::map<int,Sample> to std::map<int,Sample const&> that I reduce the number of constructed objects, and only when I delete the copy constructor that I eliminate all copies (obviously). After making both of those changes, my result includes one call to the default constructor and two calls to the destructor for the same object. I think I must be missing something. (g++ 5.4.1, c++11)– John P
Aug 30 '17 at 23:13
FWIW I agree that optimization and correctness should be completely independent, as this is exactly the kind of code you write as a sanity check after different optimization levels produce inconsistent results. In general I would recommend
emplace instead of insert if you're just constructing a value to insert immediately (and you don't want extra instances.) It's not my area of expertise, if I can even say I have one, but the copy/move semantics introduced by C++11 have helped me a lot.– John P
Aug 30 '17 at 23:31
FWIW I agree that optimization and correctness should be completely independent, as this is exactly the kind of code you write as a sanity check after different optimization levels produce inconsistent results. In general I would recommend
emplace instead of insert if you're just constructing a value to insert immediately (and you don't want extra instances.) It's not my area of expertise, if I can even say I have one, but the copy/move semantics introduced by C++11 have helped me a lot.– John P
Aug 30 '17 at 23:31
add a comment |
starting from c++11 just use uniform initialization for pairs. So instead of:
std::make_pair(1, 2);
or
std::pair<int, int>(1, 2);
just use
1, 2;
add a comment |
starting from c++11 just use uniform initialization for pairs. So instead of:
std::make_pair(1, 2);
or
std::pair<int, int>(1, 2);
just use
1, 2;
add a comment |
starting from c++11 just use uniform initialization for pairs. So instead of:
std::make_pair(1, 2);
or
std::pair<int, int>(1, 2);
just use
1, 2;
starting from c++11 just use uniform initialization for pairs. So instead of:
std::make_pair(1, 2);
or
std::pair<int, int>(1, 2);
just use
1, 2;
answered Mar 14 at 10:04
Mahmoud BadriMahmoud Badri
8908 silver badges21 bronze badges
8908 silver badges21 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9270563%2fwhat-is-the-purpose-of-stdmake-pair-vs-the-constructor-of-stdpair%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
5
In C++11, you can almost entirely do without make_pair. See my answer.
– PlagueHammer
Mar 19 '14 at 6:54
2
In C++17,
std::make_pairis redundant. There is an answer below that details this.– Drew Dormann
May 22 '18 at 14:56