2015-09-07 121 views
4

你好,我有以下代碼:的std :: make_pair與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 

經過一番小小的挖掘,我發現之前編譯的這個事實可能是一個bug;不過,我仍然不確定如何解決這個問題。有沒有人有正確的方向?

gcc --versiongcc (Debian 4.6.3-14+rpi1) 4.6.3

+3

'make_pair'應該能夠推斷出參數類型,試着刪除你明確的模板參數:'std :: make_pair(p_pinNumber,pin)' – melak47

+2

注意:'if(pin)'總是爲true或者沒有影響如果拋出異常 –

+0

@ melak47這是刪除參數允許代碼編譯的問題。謝謝! – joshu

回答

18

std::make_pair的定義已經C++ 03和C++ 11之間改變。在C++ 11中,通過轉發引用而不是的值爲,其參數爲。這意味着,通過明確其類型模板參數你結束了以下實例:

std::make_pair<std::string , boost::shared_ptr<GPIOPin> > 
      (std::string&&, boost::shared_ptr<GPIOPin>&&); 

期待右值參考,不能結合您在通過左值

你不應該傳遞類型模板參數std::make_pair明確,並讓編譯器推斷出他們自身的:

std::make_pair(p_pinNumber, pin) 
+0

謝謝,很高興知道。 C++ 14定義有一個額外的變化。 –

+0

感謝您的信息! – joshu

+1

應該強調的一點是,這確實是C++ 11中的一個突破性變化。 –

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中運行,所以不要這樣做。

我在http://advogato.org/person/redi/diary/239.html

6

報告中寫道:一個更完整的解釋是,在C++ 11的std :: make_pair往往可以有利於初始化構造

m_pinsInUse.insert({p_pinNumber, pin}); 
1

除了答案的下降@ NexusSquared提供: 您可以使用std :: map的新emplace功能:

m_pinsInUse.emplace(p_pinNumber,pin);

它甚至更短,構建std :: pair就地而不是構造它,然後將新構造的對的內容複製到地圖的內存中。

相關問題