2011-10-24 23 views
15

Trong C++, tôi đang sử dụng phép biến đổi để thay đổi tất cả các giá trị của bản đồ thành chữ hoa.Cách áp dụng biến đổi cho bản đồ STL trong C++

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); 
     }); 

này mang lại cho tôi những lỗi biên dịch sau:

/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> >&) 

Tôi nghĩ rằng có điều gì đó sai trái với các loại đối số trong biểu thức lambda tôi. Nó có thể là một cái gì đó đơn giản, nhưng tôi dường như không thể tìm ra những gì mong đợi.

+3

Thay vì giả sử một cửa hàng chứa một loại cụ thể. Bạn có thể truy cập thông tin loại thông qua value_type. 'std :: map :: value_type' –

+0

cảm ơn, tôi vẫn đang học C++ thành ngữ ... – daj

Trả lời

19

Bạn đang thiếu const trong loại đầu tiên của cặp.

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

Tuy nhiên, đây không phải là vấn đề của bạn: Bạn không thể sử dụng map làm Bộ tạo đầu ra vì chúng không hỗ trợ gán. Tuy nhiên, bạn có thể thay đổi đối số thứ hai bằng cách sử dụng std::for_each.

Tốt cũ map_to_foobar:

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

Khái niệm thứ: Gọi transform với phạm vi giống như đầu vào và đầu ra là khá hợp pháp và làm cho rất nhiều ý nghĩa nếu tất cả functors của bạn trở lại theo giá trị và không đột biến của họ lập luận. Tuy nhiên, đột biến một cái gì đó tại chỗ có thể nhanh hơn (hoặc ít nhất là nhìn nhanh hơn trong mã, không bao giờ biên dịch tối ưu hóa) và làm cho rất nhiều ý nghĩa với các chức năng thành viên.

+0

Thêm một const cho tôi một lỗi khác/opt/local/include/gcc46/c + +/bits/stl_pair.h: 156: 2: lỗi: truyền tham số 'const std :: basic_string ' như 'this' của 'std :: basic_string <_CharT, _Traits, _Alloc> & std :: basic_string <_CharT, _Traits , _Alloc> :: operator = (const std :: basic_string <_CharT, _Traits, _Alloc> &) [với _CharT = char, _Traits = std :: char_traits , _Alloc = std :: allocator , std :: basic_string <_CharT , _Traits, _Alloc> = std :: basic_string ] 'loại bỏ vòng loại [-fpermissive] – daj

+0

@daj Xin lỗi, tôi đã nhận ra muộn. Bản chỉnh sửa giải thích nó. – pmr

+2

Ngoài ra, bạn có thể sử dụng 'std :: transform' với biến lặp. Ví dụ: 'key_iterator' của tôi, được đăng trong [câu trả lời cho một câu hỏi khác] (http://stackoverflow.com/questions/2467000/is-there-a-java-map-keyset-equivalent-for-cs-stdmap/ 5099345 # 5099345), có thể được trivially chuyển đổi thành một 'value_iterator'. Sau đó, bạn sẽ kết thúc với 'std :: transform (begin_values ​​(dữ liệu), end_values ​​(dữ liệu), begin_values ​​(data), [] (std :: string s) {boost :: to_upper (s); return s;}); Trong trường hợp này, tôi đề nghị 'std :: for_each', bởi vì nó loại bỏ bản sao không cần thiết. –

Các vấn đề liên quan