2010-02-25 28 views
6

Sử dụng & để lấy địa chỉ của một biến có thể có vấn đề nếu kiểu biến đã quá tải operator&(). Ví dụ: _com_ptr_operator&() bị quá tải với tác dụng phụ của việc sửa đổi đối tượng.Cách di động và đáng tin cậy nhất để lấy địa chỉ biến trong C++

Bây giờ tôi có một tập hợp phức tạp của các mẫu với các chức năng như thế này:

template<class T> 
void process(const T* object) 
{ 
    //whatever 
}  

template<class T> 
void tryProcess(T& object) 
{ 
    process(&object) 
} 

Trong tryProcess() tôi cần để có được một con trỏ T* giữ địa chỉ của đối tượng thực tế của loại T.

Việc triển khai trên tryProcess() sẽ chỉ hoạt động hoàn toàn nếu class T không bị quá tải operator&(). Vì vậy, nếu tôi gọi tryProcess<_com_ptr_<Interface>>() Tôi có thể nhận được kết quả không mong muốn - quá tải operator&() được kích hoạt.

Trong another question các workaround sau đây là suggested:

template<class T> 
T* getAddress(T& object) 
{ 
    return reinterpret_cast<T*>(&reinterpret_cast<char&>(object)); 
} 

Với chức năng như vậy tôi có thể thực hiện tryProcess() như sau:

template<class T> 
void tryProcess(T& object) 
{ 
    process(getAddress(object)) 
} 

và sẽ luôn luôn nhận được cùng một độc lập hành vi của liệu class Toperator&() quá tải. Điều này giới thiệu số không trên không với tối ưu hóa trên trên Visual C++ 7 - trình biên dịch được những gì để làm và chỉ nhận được địa chỉ đối tượng.

Làm cách nào để giải quyết vấn đề này? Làm thế nào nó có thể được cải thiện?

+0

Để tham khảo các độc giả sau này: C++ 11 được chuẩn hóa một phiên bản gọn gàng (trước đây là 'tăng cường') của thành ngữ này, như' std :: addressof': http://en.cppreference.com/w/cpp/ bộ nhớ/addressof' –

Trả lời

3

Đó là khiếu nại chuẩn. Vấn đề đã được đưa đến sự chú ý của ủy ban ISO C++ liên quan đến các vấn đề với việc triển khai offsetof đã phá vỡ vấn đề này. Trong số các giải pháp được xem xét là thắt chặt định nghĩa POD, hoặc thêm một hạn chế thêm vào các loại được sử dụng với offsetof. Những giải pháp này đã bị từ chối khi giải pháp reinterpret_cast được đưa ra. Vì điều này cung cấp một cách tuân thủ tiêu chuẩn xung quanh vấn đề, ủy ban không thấy cần phải thêm các yêu cầu bổ sung vào offsetof và các bản sửa lỗi còn lại cho các triển khai.

4

Boost addressof được triển khai với mẹo đó reinterpret_cast vì vậy tôi cho rằng đó có thể là thiết bị di động và phù hợp tiêu chuẩn.

Here bạn có thể xem mã được đề cập.

+2

và may mắn thay, người ta không còn cần 'tăng', vì đây là bây giờ' std :: addressof': http://en.cppreference.com/w/cpp/memory/addressof –

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