2017-05-15 27 views
4

我已經試過我的問題縮小到最小的例子:Lambda和地圖,通過引用參數:param - 編譯出錯

#include <algorithm> 
#include <map> 
#include <string> 
#include <vector> 

int main() 
{ 
    std::vector<int> result; 
    std::map<std::string, std::pair<unsigned int, std::vector<int>>> other; 

    if (true) 
    { 
     std::for_each(other.begin(), other.end(), 
      [&](std::pair<std::string, std::pair<unsigned int, std::vector<int>>> & data) 
      { 
       result.insert(result.end(), data.second.second.begin(), data.second.second.end()); 
      }); 
    } 

    return 0; 
} 

我得到一個編譯錯誤:

error C2664: 'void main::<lambda_1b93236899a42921c1aec8d5288e5b90>::operator()(std::pair<std::string,std::pair<unsigned int,std::vector<int,std::allocator<_Ty>>>> &) const': cannot convert argument 1 from 'std::pair<const _Kty,_Ty>' to 'std::pair<std::string,std::pair<unsigned int,std::vector<int,std::allocator<_Ty>>>> &' 

至於我可以告訴lambda參數的確是對我們迭代的地圖所包含的類型的引用。這是我應該使用的類型,對吧?

如果我在data之前刪除了amperstand,它會進行編譯。

爲什麼?

我不想按價值傳遞每個元素,因爲這些集合在我的真實程序中將包含大量數據。

如果我用auto &替換lambda參數,它會編譯,這導致我相信lambda參數中的類型與映射中包含的類型不匹配,但它確實看起來像它對我的樣子。另外,如果原型編譯沒有&,如果類型錯誤呢?

我在想什麼/沒有理解?

+0

我在原始代碼中輸入了所有這些東西,我想在這裏的示例中明確指出,以便發現任何我不知道的潛在問題。 –

+1

您在密鑰類型上缺少'const'。使用'[&](decltype(other):: value_type&)'或'[&](auto&)'。 – Oktalist

+0

@Oktalist今天花了我幾個小時弄清楚:-P –

回答

6

std::map<Key, T>value_typestd::pair<const Key, T>而不是std::pair<Key, T>。沒有&符號的版本會製作每對的副本。既然你可以複製const KeyKey一切都很好。將const添加到您的lambda的參數類型。

#include <algorithm> 
#include <map> 
#include <string> 
#include <vector> 

int main() 
{ 
    std::vector<int> result; 
    std::map<std::string, std::pair<unsigned int, std::vector<int>>> other; 

    if (true) 
    { 
     std::for_each(other.begin(), other.end(), 
      [&](std::pair<const std::string, std::pair<unsigned int, std::vector<int>>> & data) 
     // Add this const ^^^^^ 
     { 
      result.insert(result.end(), data.second.second.begin(), data.second.second.end()); 
     }); 
    } 

    return 0; 
} 
3

我一直在苦苦掙扎,今天遇到了同樣的問題。

我解決了製作鍵值類型的std::pairconst

[&](std::pair<const std::string, std::pair<unsigned int, std::vector<int>>> & data) 
      // ^^^^^ 

想着說了一下後,這是很合乎邏輯:
你不能改變一個std::map的條目的key_value的東西不同。因此,如果它與auto循環一起工作,並且需要將其指定爲const