2012-08-11 35 views
6

Đây có phải là C++ hợp lệ (xem xét tiêu chuẩn mới nhất) không? Tôi đang nhận được lỗi biên dịch với clang/libC++ gần trên cùng của cây trên Ubuntu 12.04. Nếu nó hợp lệ, tôi sẽ gửi danh sách clang-dev bằng các thông báo lỗi và như vậy.Isordered_set <reference_wrapper <Ty>> hợp lệ?

#include <functional> 
#include <unordered_set> 

struct X 
{ 
    int i; 
}; 

void f() 
{ 
    std::unordered_set<std::reference_wrapper<X>> setOfReferencesToX; 

    // Do stuff with setOfReferencesToX 
} 

** Ngoài ra, tôi cảm thấy mệt mỏi khi đủ điều kiện câu hỏi/câu trả lời dành riêng cho tiêu chuẩn mới nhất. Có thể cộng đồng C++ nói chung không, hãy bắt đầu đủ điều kiện cụ thể cho tiêu chuẩn cũ thay thế? Các tiêu chuẩn mới hơn đã được ra cho khoảng một năm nay.

+1

+1 cho ghi chú kết thúc. – Griwes

+0

"Cộng đồng C++ có thể là một tổng thể không, hãy bắt đầu đủ điều kiện cụ thể cho tiêu chuẩn cũ thay thế?" Với số lượng người dùng tuyệt đối không thể nâng cấp lên trình biên dịch với sự hỗ trợ C++ 11 hoàn chỉnh hơn, hãy để sự nổi tiếng của một gia đình biên dịch nào đó mà chỉ từ từ nâng cấp nó là hỗ trợ C++ 11, C++ sẽ có nghĩa là C++ 03 trong ít nhất một năm nếu không phải là hai. Và đừng quên rằng cả GCC lẫn Clang đều không tuân thủ đầy đủ C++ 11. Tương lai không phải là hiện tại, và giả vờ rằng nó sẽ không làm cho nó như vậy. –

Trả lời

8

Sự cố không cụ thể đối với std::reference_wrapper<T>, nhưng thay vào đó chính là loại X.

Vấn đề là std::unordered_set yêu cầu bạn xác định hàm băm và bình đẳng cho std::reference_wrapper<X>. Bạn có thể chuyển hàm băm functor thành tham số mẫu thứ hai.

Ví dụ, điều này sẽ làm việc:

#include <functional> // for std::hash<int> 

struct HashX { 
    size_t operator()(const X& x) const { 
    return std::hash<int>()(x.i);  
    } 
}; 

và sau đó

std::unordered_set<std::reference_wrapper<X>, HashX> setOfReferencesToX; 

lựa chọn khác là để thực hiện một chuyên môn hóa cho std::hash<X>:

namespace std { 
template <> 
struct hash<X> { 
    size_t operator()(const X& x) const { 
    return std::hash<int>()(x.i);  
    } 
}; 
} 

này cho phép bạn để tránh một cách rõ ràng chỉ định đối số mẫu thứ hai:

std::unordered_set<std::reference_wrapper<X>> setOfReferencesToX; 

Liên quan đến việc so sánh bình đẳng, bạn có thể sửa lỗi này bằng cách cung cấp một nhà điều hành bình đẳng cho các lớp học X:

struct X 
{ 
    bool operator==(const X& rhs) const { return i == rhs.i; } 
    int i; 
}; 

Nếu không, bạn có thể định nghĩa functor của riêng bạn và vượt qua nó như mẫu số thứ ba.

+0

Sẽ không chuyên 'std :: hash' là một chút đơn giản? – Griwes

+0

Nó sẽ, nếu bạn sẵn sàng để đặt công cụ trong không gian tên 'std'. – juanchopanza

+0

Tôi không nghĩ rằng nó phải đủ điều kiện như "đặt công cụ trong' std' ", vì nó chỉ là chuyên môn hóa ... – Griwes

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