2012-03-05 12 views
5

Tôi đã một lớp có chứa một bản đồđiều hành quá tải không ném ngoại lệ

Any& Map::operator[](const unsigned int field) const 
{ 
    try 
    { 
    iterator it; 
    if ((it = m_fields.find(field)) != m_fields.end()) 
     return it->second; 

    throw std::runtime_error("Field " + boost::lexical_cast<std::string>(field) + " not found."); 
    } 
    catch(boost::bad_any_cast&) 
    { 
    throw std::runtime_error("Failed conversion field " + boost::lexical_cast<std::string>(field) + " using boost::any_cast "); 
    } 
} 

Tôi muốn nó ném một ngoại lệ khi lĩnh vực này không tồn tại trong bản đồ để chương trình không sụp đổ trên get xấu, nhưng cú ném dường như không hoạt động trên toán tử bị quá tải, chương trình vẫn bị treo do đó việc ném hoặc bắt bị bỏ qua. Nếu tôi sử dụng cùng một mã nhưng có chức năng chung là

Any& Map::get(const unsigned int field) const 
{ 
    //... 

hoạt động.

Tôi đã chạy trong một số giới hạn C++ hay tôi đang làm điều gì đó sai?

--edit:

Tôi chạy trình gỡ lỗi và trước sự ngạc nhiên của tôi mã mà thậm chí không thực hiện, phương pháp khác thì

Any& Map::operator[](const unsigned int field) 
{ 
    iterator it; 
    if ((it = m_fields.find(field)) == m_fields.end()) 
    { 
    Any newValue; 
    m_fields[field] = newValue; 
    return m_fields[field]; 
    } 

    return it->second; 
} 

và vụ tai nạn xảy ra do một sự thúc đẩy khẳng định trên Bất kỳ điều gì cố gắng chuyển đổi biến chưa được khởi tạo. Phương pháp này có lẽ được sử dụng trên chèn trên bản đồ, như

Map a; 
a[3] = "foo"; 

Vì vậy, tôi đoán tôi không có cách nào để phân biệt khi các nhà điều hành được sử dụng trên một atribution hoặc trên một get và việc sử dụng các toán tử này rất không an toàn cho được

+0

Cá nhân tôi sẽ đưa 'find' và sự so sánh trên các dòng khác nhau – pkit

+1

Đó là (có thể) không phải là nguyên nhân gây ra sự cố của bạn, nhưng bạn sẽ cần phải trả về theo giá trị - bạn không thể trả lại tham chiếu đến tạm thời. –

+0

@pkit Và khởi tạo 'it' trong câu lệnh xác định nó. –

Trả lời

2

Chỉnh sửa của bạn: độ phân giải quá tải thường chỉ tính đến các đối số , không sử dụng. Nếu bạn có hàm const và không phải là const nếu không có chữ ký giống hệt nhau, thì không phải const sẽ được chọn nếu có thể (ví dụ: được gọi trên đối tượng không phải const).

Trong trường hợp bạn muốn có hành vi khác nhau tùy thuộc vào việc sử dụng, giải pháp truyền thống là cung cấp proxy. lớp Map bạn sẽ chứa hai chức năng getset, và không const operator[] sẽ quay trở lại một proxy mà trông giống như sau:

class Proxy // member of Map 
{ 
    Map* myOwner; 
    int myIndex; 
public: 
    Proxy(Map* owner, int index) 
     : myOwner(owner) 
     , myIndex(index) 
    { 
    } 
    void operator=(Any const& rhs) const 
    { 
     myOwner->put(myIndex, rhs); 
    } 
    operator Any() const 
    { 
     return myOwner->get(myIndex); 
    } 
}; 
+0

+1 cho proxy. Mẫu 'Proxy'" thường bị bỏ qua mặc dù nó có lẽ là một trong những mẫu biến động nhất mà tôi đã thấy. –