2016-01-03 15 views
9

Tôi có một số std::unordered_multimap và tôi muốn lấy phần tử được chèn cuối cùng của một khóa cụ thể. Tôi quan sát thấy hành vi này:Tôi có thể dựa vào thứ tự của một bản đồ không có thứ tự không?

#include <iostream> 
#include <string> 
#include <unordered_map> 

using namespace std; 

int main() { 
    unordered_multimap<string, string> mmap; 

    mmap.emplace("a", "first"); 
    mmap.emplace("a", "second"); 
    mmap.emplace("a", "last"); 
    mmap.emplace("b", "1"); 
    mmap.emplace("b", "2"); 
    mmap.emplace("b", "3"); 

    auto last_a = mmap.equal_range("a").first; 
    auto last_b = mmap.equal_range("b").first; 

    cout << last_a->second << endl; 
    cout << last_b->second << endl; 

    return 0; 
} 

Mã này kết quả đầu ra:

last 
3 

này được, ít nhất, trên GCC, hành vi tôi muốn. Tôi có thể dựa vào điều này? Liệu tiêu chuẩn có mô phỏng về thứ tự các trang std::unordered_multimap lưu trữ không? Nếu không, điều gì sẽ là lựa chọn tốt nhất?

+0

Bạn sẽ nhận được 'đầu tiên 1' với [libC++] (http://coliru.stacked-crooked.com/a/f8f56abb25674bbe). –

Trả lời

8

Hầu như.

[C++14: 24.2.5/6]:[..] Trong container có hỗ trợ các phím tương đương, các yếu tố với các phím tương đương là liền kề với nhau theo thứ tự lần lặp của container. Do đó, mặc dù thứ tự tuyệt đối của các phần tử trong một vùng chứa không theo thứ tự không được chỉ định, các phần tử của nó được nhóm thành các nhóm khóa tương đương sao cho tất cả các phần tử của mỗi nhóm có khóa tương đương. Thao tác đột biến trên vùng chứa không có thứ tự sẽ bảo toàn thứ tự các phần tử tương đối trong mỗi nhóm khóa tương đương trừ khi có quy định khác.

[C++14: 24.2.5/9]:[..]Đối unordered_multiset và unordered_multimap, chước hay rập khuôn giữ gìn trật tự tương đối của các yếu tố tương đương.

Nó khá vụng về từ ngữ nhưng, từ những gì tôi có thể nói, khái niệm chung là thứ tự của các yếu tố bên dưới các phím tương đương là không xác định, mặc dù nó ít nhất khá nhiều vẫn như cũ sau đó.

Vì vậy:

Bạn không thể dựa vào trật tự chèn, nhưng có thể bạn có thể dựa vào một trật tự ổn định nếu bạn cẩn thận.

Điều này trái ngược với các container kết hợp ra lệnh:

[C++14: 23.2.4/4]:Đối MultiSet và Multimap, chèn, đặt vào một chỗ, và xóa giữ gìn trật tự tương đối của các yếu tố tương đương.

+4

Nhưng nó không được chỉ định nơi phần tử mới được chèn vào. Nếu bạn có 'a, b, c' trong nhóm khóa tương đương và chèn' d', thứ tự tương đối của 'a',' b' và 'c' sẽ không thay đổi, nhưng bạn có thể chèn' d ở bất kỳ nơi nào trong bốn địa điểm. –

+0

@ T.C. Có thể hoặc không được ok –

1

std::unordered_multimap không phải là ra lệnh (rõ ràng) cũng không ổn định. Vì vậy, thứ tự bạn đặt các phần tử tương đương vào std::unordered_multimap là không có cách nào được đảm bảo để phù hợp theo tiêu chuẩn.

+0

Từ ngữ gợi ý mức độ ổn định cao. –

+0

@LightnessRacesinOrbit phần tử tương đương chỉ được đảm bảo nằm trong một thứ tự tiếp giáp của thứ tự lặp lại. –

+0

@P aulEvans Tôi biết. –

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