Hello I have the following code:
bool PinManager::insertPin(const std::string& p_pinNumber, const std::string& p_mode)
{
boost::shared_ptr<GPIOPin> pin(new GPIOPin(p_pinNumber, p_mode));
if (pin)
{
m_pinsInUse.insert(std::make_pair<std::string, boost::shared_ptr<GPIOPin> >(p_pinNumber, pin));
return true;
}
return false;
}
This code has always compiled, but when I added the -std=c++0x
flag this code fails to compile with the message:
[ 42%] Building CXX object gpioaccess/CMakeFiles/gpioaccess.dir/pinmanager/pinmanager.cpp.o
/home/pi/robot_2.0/trunk/gpioaccess/pinmanager/pinmanager.cpp: In member function 'bool gpioaccess::PinManager::insertPin(const string&, const string&)':
/home/pi/robot_2.0/trunk/gpioaccess/pinmanager/pinmanager.cpp:39:101: error: no matching function for call to 'make_pair(const string&, boost::shared_ptr<gpioaccess::GPIOPin>&)'
/home/pi/robot_2.0/trunk/gpioaccess/pinmanager/pinmanager.cpp:39:101: note: candidate is:
/usr/include/c++/4.6/bits/stl_pair.h:262:5: note: template<class _T1, class _T2> std::pair<typename std::__decay_and_strip<_T1>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)
gpioaccess/CMakeFiles/gpioaccess.dir/build.make:77: recipe for target 'gpioaccess/CMakeFiles/gpioaccess.dir/pinmanager/pinmanager.cpp.o' failed
make[2]: *** [gpioaccess/CMakeFiles/gpioaccess.dir/pinmanager/pinmanager.cpp.o] Error 1
CMakeFiles/Makefile2:75: recipe for target 'gpioaccess/CMakeFiles/gpioaccess.dir/all' failed
make[1]: *** [gpioaccess/CMakeFiles/gpioaccess.dir/all] Error 2
Makefile:75: recipe for target 'all' failed
make: *** [all] Error 2
After doing a little digging I found that the fact this compiled before was probably a bug; however, I am still unsure how to fix this. Does anyone have any points in the correct direction?
gcc --version
is gcc (Debian 4.6.3-14+rpi1) 4.6.3
The make_pair() function, which comes under the Standard Template Library of C++, is mainly used to construct a pair object with two elements. In other words, it is a function that creates a value pair without writing the types explicitly.
Another way to initialize a pair is by using the make_pair() function. g2 = make_pair(1, 'a'); Another valid syntax to declare pair is: g2 = {1, 'a'};
std::pair is a class template that provides a way to store two heterogeneous objects as a single unit. A pair is a specific case of a std::tuple with two elements. If neither T1 nor T2 is a possibly cv-qualified class type with non-trivial destructor, or array thereof, the destructor of pair is trivial.
std::pair is not a Container. Its intention is to group two objects together. Instance of the std::pair is a class with two member objects.
std::make_pair
has changed between c++03 and c++11.
In c++11, it accepts parameters by forwarding-references rather than by value. This means that by specifying its type template arguments explicitly you end up with the following instantiation:
std::make_pair<std::string , boost::shared_ptr<GPIOPin> >
(std::string&&, boost::shared_ptr<GPIOPin>&&);
expecting rvalue references, which cannot bind to lvalues.
You should not specify type template arguments of std::make_pair
explicitly. Instead, you should let the compiler deduce them on its own:
std::make_pair(p_pinNumber, pin)
Additionally, since c++11, when using std::map
, you can construct the pair in-place:
m_pinsInUse.emplace(p_pinNumber, pin);
In c++17 you can utilize class template argument deduction, and construct std::pair
without specifying class template arguments:
std::pair(p_pinNumber, pin)
The whole point of std::make_pair
is to simplify creating a std::pair
so you don't need to specify the template arguments, letting the compiler deduce them.
If you call std::make_pair<T, U>(t, u)
with explicit template arguments then you are defeating the entire purpose of the function, because you are preventing deduction, and you're wasting time typing extra characters and potentially creating unnecessary copies of objects, when you could just do std::pair<T, U>(t, u)
instead (saving yourself from typing five extra, useless characters).
If you use std::make_pair
the way it's intended to be used then you won't even notice that it changed in C++11. If you misuse it by pointlessly providing template arguments then it might not work in C++11, so don't do that.
I wrote a more complete explanation at http://advogato.org/person/redi/diary/239.html
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