Std :: make_pair: cannot convert 'ch' (type 'char') to type 'char &&'

What is wrong with the following code:

#include <ctime> #include <vector> #include <utility> #include <algorithm> #include <iostream> int main() { std::vector< std::pair< char, unsigned > > vec; for( unsigned i = 0; i < 100; ++i ) { char ch = 0; unsigned number = 0; do { ch = i; number = i; } while( std::find( vec.begin(), vec.end(), std::make_pair< char, unsigned >( ch, number ) ) != vec.end() ); std::cout << ch << number << '\n'; vec.push_back( std::make_pair< char, unsigned >( ch, number ) ); } } 

It compiles fine with:

 g++ test.cxx 

but with an error:

 $ g++ -std=c++11 test.cxx /tmp test.cxx: In function 'int main()': test.cxx:21:98: error: no matching function for call to 'make_pair(char&, unsigned int&)' test.cxx:21:98: note: candidate is: In file included from /usr/include/c++/4.7/bits/stl_algobase.h:65:0, from /usr/include/c++/4.7/vector:61, from test.cxx:3: /usr/include/c++/4.7/bits/stl_pair.h:268:5: note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&) /usr/include/c++/4.7/bits/stl_pair.h:268:5: note: template argument deduction/substitution failed: test.cxx:21:98: note: cannot convert 'ch' (type 'char') to type 'char&&' test.cxx:25:69: error: no matching function for call to 'make_pair(char&, unsigned int&)' test.cxx:25:69: note: candidate is: In file included from /usr/include/c++/4.7/bits/stl_algobase.h:65:0, from /usr/include/c++/4.7/vector:61, from test.cxx:3: /usr/include/c++/4.7/bits/stl_pair.h:268:5: note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&) /usr/include/c++/4.7/bits/stl_pair.h:268:5: note: template argument deduction/substitution failed: test.cxx:25:69: note: cannot convert 'ch' (type 'char') to type 'char&&' 
+6
source share
1 answer

DECISION:

Instead of explicitly specifying make_pair<>() template arguments as follows:

 std::make_pair< char, unsigned >( ch, number ) 

Just let them be deduced:

 std::make_pair( ch, number ) 

EXPLANATION:

The rationale for this guide is found in the method for defining std::make_pair<>() and in the method of subtracting the template argument for universal references. From clause 20.3.3 / 8-9 of the C ++ 11 standard:

template <class T1, class T2> pair<V1, V2> make_pair(T1&& x, T2&& y);

Returns: pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y)); where V1 and V2 are defined as follows: let Ui decay<Ti>::type for each Ti . Then each Vi is equal to X& , if Ui is equal to reference_wrapper<X> , otherwise Vi is Ui . [Example: instead of:

return pair<int, double>(5, 3.1415926); // explicit types

C ++ program may contain:

return make_pair(5, 3.1415926); // types are deduced

-end example]

It is assumed that T1 and T2 . make_pair<>() setting the template arguments themselves, you get in the way of the make_pair<>() type inference mechanism to get the correct return type, forcing you to instantiate a function that accepts an rvalue reference to char and an rvalue reference to unsigned :

 ... make_pair(char&&, unsigned&&) 

However, you do not provide rvalues ​​in the input because ch and number are lvalues. This is what the compiler is complaining about.


ALTERNATIVE:

Also note that you can implicitly build a std::pair object that fully saves your call to make_pair<>() :

 vec.push_back( { ch, number } ); 
+14
source

All Articles