std::make_pair 使用 C++ 11
std::make_pair with c++ 11
您好,我有以下代码:
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;
}
此代码始终可以编译,但是当我添加 -std=c++0x
标志时,此代码无法编译并显示消息:
[ 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
经过一番挖掘,我发现之前编译的这个事实可能是一个错误;但是,我仍然不确定如何解决这个问题。有没有人在正确的方向上有任何要点?
gcc --version
是 gcc (Debian 4.6.3-14+rpi1) 4.6.3
std::make_pair
has changed between c++03 and c++11.
在 c++11 中,它接受参数 by forwarding-references 而不是 by value。这意味着通过显式指定其类型模板参数,您最终会得到以下实例化:
std::make_pair<std::string , boost::shared_ptr<GPIOPin> >
(std::string&&, boost::shared_ptr<GPIOPin>&&);
需要 右值 引用,不能绑定到左值。
您不应明确指定 std::make_pair
的类型模板参数。相反,你应该让编译器自己推导它们:
std::make_pair(p_pinNumber, pin)
此外,由于 c++11,当使用 std::map
时,您可以就地构建对:
m_pinsInUse.emplace(p_pinNumber, pin);
在 c++17 中,您可以利用 class 模板参数推导,并在不指定 class 模板参数的情况下构造 std::pair
:
std::pair(p_pinNumber, pin)
std::make_pair
的全部意义在于简化 std::pair
的创建,因此您无需指定模板参数,让编译器推导它们。
如果您使用显式模板参数调用 std::make_pair<T, U>(t, u)
那么您将破坏该函数的全部目的,因为您阻止了推导, 和 您是在浪费时间输入额外的字符并可能创建不必要的对象副本,而您可以只执行 std::pair<T, U>(t, u)
(避免输入五个额外的无用字符)。
如果您按照预期的方式使用 std::make_pair
,那么您甚至不会注意到它在 C++11 中发生了变化。如果您通过毫无意义地提供模板参数来滥用它,那么它可能无法在 C++11 中工作,所以不要那样做。
写了更完整的解释
请注意,在 c++11 中,通常可以删除 std::make_pair 以支持初始化构造函数
m_pinsInUse.insert({p_pinNumber, pin});
除了@NexusSquared 提供的答案:
您可以只使用 std::map:
的新 emplace 函数
m_pinsInUse.emplace(p_pinNumber, 别针);
它甚至更短,并就地构造 std::pair 而不是构造它,然后将新构造的对的内容复制到地图的内存中。
您好,我有以下代码:
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;
}
此代码始终可以编译,但是当我添加 -std=c++0x
标志时,此代码无法编译并显示消息:
[ 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
经过一番挖掘,我发现之前编译的这个事实可能是一个错误;但是,我仍然不确定如何解决这个问题。有没有人在正确的方向上有任何要点?
gcc --version
是 gcc (Debian 4.6.3-14+rpi1) 4.6.3
std::make_pair
has changed between c++03 and c++11.
在 c++11 中,它接受参数 by forwarding-references 而不是 by value。这意味着通过显式指定其类型模板参数,您最终会得到以下实例化:
std::make_pair<std::string , boost::shared_ptr<GPIOPin> >
(std::string&&, boost::shared_ptr<GPIOPin>&&);
需要 右值 引用,不能绑定到左值。
您不应明确指定 std::make_pair
的类型模板参数。相反,你应该让编译器自己推导它们:
std::make_pair(p_pinNumber, pin)
此外,由于 c++11,当使用 std::map
时,您可以就地构建对:
m_pinsInUse.emplace(p_pinNumber, pin);
在 c++17 中,您可以利用 class 模板参数推导,并在不指定 class 模板参数的情况下构造 std::pair
:
std::pair(p_pinNumber, pin)
std::make_pair
的全部意义在于简化 std::pair
的创建,因此您无需指定模板参数,让编译器推导它们。
如果您使用显式模板参数调用 std::make_pair<T, U>(t, u)
那么您将破坏该函数的全部目的,因为您阻止了推导, 和 您是在浪费时间输入额外的字符并可能创建不必要的对象副本,而您可以只执行 std::pair<T, U>(t, u)
(避免输入五个额外的无用字符)。
如果您按照预期的方式使用 std::make_pair
,那么您甚至不会注意到它在 C++11 中发生了变化。如果您通过毫无意义地提供模板参数来滥用它,那么它可能无法在 C++11 中工作,所以不要那样做。
请注意,在 c++11 中,通常可以删除 std::make_pair 以支持初始化构造函数
m_pinsInUse.insert({p_pinNumber, pin});
除了@NexusSquared 提供的答案: 您可以只使用 std::map:
的新 emplace 函数m_pinsInUse.emplace(p_pinNumber, 别针);
它甚至更短,并就地构造 std::pair 而不是构造它,然后将新构造的对的内容复制到地图的内存中。