2011-10-24 61 views
15

在C++中,我使用轉換將地圖的所有值更改爲大寫。如何將轉換應用於C++中的STL映射

std::map<std::string, std::string> data = getData(); 

    // make all values uppercase 
    std::transform(data.begin(), data.end(), data.begin(), 
     [](std::pair<std::string, std::string>& p) { 
      boost::to_upper(p.second); 
      return(p); 
     }); 

這給了我下面的編譯錯誤:

/opt/local/include/gcc46/c++/bits/stl_algo.h:4805:2: error: no match for call to '(main(int, char**)::<lambda(std::pair<std::basic_string<char>, std::basic_string<char> >&)>) (std::pair<const std::basic_string<char>, std::basic_string<char> >&) 

我覺得有些不對勁與參數的類型在我的lambda表達式。這可能很簡單,但我似乎無法弄清楚預期的結果。

+3

而不是假設容器存儲特定類型。您可以通過value_type訪問類型信息。 'std :: map :: value_type' –

+0

謝謝,我還在學習C++習語... – daj

回答

19

您在第一對類型中缺少const。

[](std::pair<const std::string, std::string>& p) { 

然而,這不是你的問題:你不能使用map作爲輸出迭代,因爲他們不支持的任務。但是,您可以使用std::for_each變更第二個參數。

好老map_to_foobar

std::for_each(data.begin(), data.end(), 
       [](std::pair<const std::string, std::string>& p) { 
       p.second = "foobar"; 
       }); 

概念性的東西:調用transform與同一範圍內的輸入和輸出是非常合法的,並使得很多的意義,如果你所有的仿函數由返回值,不發生變異的參數。但是,就地變異可能會更快(或者至少在代碼中看起來更快,從不會優化編譯器),並且對成員函數有很大的意義。

+0

添加一個常量會給我另一個錯誤/ opt/local/include/gcc46/C++/bits/stl_pair.h:156:2:error:將'const std :: basic_string '作爲'std :: basic_string <_CharT,_Traits,_Alloc>&std :: basic_string <_CharT,_Traits ,_Alloc> :: operator =(const std :: basic_string <_CharT,_Traits,_Alloc>&)[with _CharT = char,_Traits = std :: char_traits ,_Alloc = std :: allocator ,std :: basic_string <_CharT ,_Traits,_Alloc> = std :: basic_string ]'丟棄限定符[-fpermissive] – daj

+0

@daj對不起,我意識到遲到了。編輯解釋它。 – pmr

+2

或者,您可以對變換迭代器使用'std :: transform'。例如,我的'key_iterator',張貼在[另一個問題的答案](http://stackoverflow.com/questions/2467000/is-there-a-java-map-keyset-equivalent-for-cs-stdmap/ 5099345#5099345),可以簡單地轉換爲'value_iterator'。那麼你最終會得到'std :: transform(begin_values(data),end_values(data),begin_values(data),[](std :: string s){boost :: to_upper(s); return s;} );'。在這種情況下,我建議使用'std :: for_each',因爲它消除了不必要的副本。 –