I was doing the problem 337 from leetcode. This is the code I implemented.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
*
TL;DR: Don't specify template arguments of std::make_pair
. Let the compiler deduce them.
The meaning of template parameters of std::make_pair was changed in C++11.
It used to be:
template <class T1, class T2> /*...*/ make_pair( T1 t, T2 u );
But now it is:
template <class T1, class T2> /*...*/ make_pair(T1 &&t, T2 &&u);
// `t` and `u` are forwarding references.
The code was valid pre-C++11, but it no longer is.
You could change the template arguments accordingly: make_pair<TreeNode*&, int&>(root, result)
, but there is no reason to specify them manually. The compiler can deduce them just fine.
If you don't understand why the template arguments have to be references, read about forwarding references.
Why ... the arguments in
make_pair<>()
become references?
Probably your compiler displayed argument types as references to indicate that you're passing lvalues into make_pair
.
When you have a
unordered_map<TreeNode*, int>& memo
and you want to insert an element:
memo.insert(make_pair<TreeNode*, int>(root, result));
There are several overloads that would match. My guess (but please think about this a bit) is that you want the one taking a const value_type&
as argument. In that case, just construct the pair doing exactly that:
memo.insert(unordered_map<TreeNode*, int>::value_type(root, result));
The sole reason why you use make_pair()
is to let the compiler pick the template parameters (less typing, a generic pair<type1, type2>
ctor). If you want to specify the types explicitly, you can use the plain pair
ctor. In this case though, I'd consider it an implementation detail of unordered_map
and instead use its nested typedef. That typedef is btw. std::pair<const Key, T>
!
All this leaves me with one question only: Why not use memo[root] = result
?