std :: make_pair with c ++ 11

时间:2015-09-07 16:54:59

标签: c++ c++11 gcc boost raspberry-pi

您好我有以下代码:

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 --versiongcc (Debian 4.6.3-14+rpi1) 4.6.3

4 个答案:

答案 0 :(得分:21)

std::make_pair之间发生了变化。

中,它接受参数 by forwarding-references 而不是按值。这意味着通过明确指定其类型模板参数,您最终会得到以下实例化:

public/javascript/exclude-me/*

期待 rvalue 引用,它们无法绑定到左值。

您不应明确指定std::make_pair<std::string , boost::shared_ptr<GPIOPin> > (std::string&&, boost::shared_ptr<GPIOPin>&&); 的类型模板参数。相反,你应该让编译器自己推导出它们:

std::make_pair

此外,自起,使用std::make_pair(p_pinNumber, pin) 时,您可以就地构建对:

std::map

中,您可以利用类模板参数推导,并在不指定类模板参数的情况下构造m_pinsInUse.emplace(p_pinNumber, pin);

std::pair

答案 1 :(得分:7)

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中不起作用,所以不要这样做。

我在.count

写了一个更完整的解释

答案 2 :(得分:6)

请注意,在c ++ 11中,经常可以删除std :: make_pair以支持初始化构造函数

m_pinsInUse.insert({p_pinNumber, pin});

答案 3 :(得分:1)

除了@NexusSquared提供的答案: 你可以使用std :: map的新emplace函数:

m_pinsInUse.emplace(p_pinNumber,pin);

甚至更短,并构造std :: pair inplace而不是构造它,然后将新构造的对的内容复制到地图的内存中。