2009-01-19 30 views
53

Trong C++ đoạn mã sau đưa ra một lỗi biên dịch:Destructors các loại BUILTIN (int, char vv ..)

void destruct1 (int * item) 
{ 
    item->~int(); 
} 

Mã này là gần như nhau, tôi chỉ typedef int để một loại và một cái gì đó kỳ diệu xảy ra:

typedef int myint; 

void destruct2 (myint * item) 
{ 
    item->~myint(); 
} 

Tại sao mã thứ hai hoạt động? Có một int được một destructor chỉ vì nó đã được typedefed?

Trong trường hợp bạn tự hỏi tại sao người ta lại muốn làm điều này: Điều này xuất phát từ việc mã hóa lại mã C++. Chúng tôi đang loại bỏ heap tiêu chuẩn và thay thế nó bằng các hồ bơi tự tạo. Điều này đòi hỏi chúng ta phải gọi vị trí mới và các destructors. Tôi biết rằng việc gọi destructors cho các kiểu nguyên thủy là vô dụng, nhưng chúng ta vẫn muốn chúng trong mã trong trường hợp chúng ta thay thế POD bằng các lớp thực.

Phát hiện ra rằng int của thường không hoạt động nhưng những thứ được đánh máy thực sự là một điều bất ngờ.

Btw - Tôi có giải pháp liên quan đến chức năng mẫu. Chúng tôi chỉ cần gõ vào bên trong mẫu và mọi thứ đều ổn.

Trả lời

77

Đó là lý do khiến mã của bạn hoạt động cho các thông số chung. Xem xét vùng chứa C:

template<typename T> 
struct C { 
    // ... 
    ~C() { 
     for(size_t i = 0; i<elements; i++) 
      buffer[i].~T(); 
    } 
}; 

Sẽ gây phiền toái khi giới thiệu các trường hợp đặc biệt đối với loại được cài sẵn. Vì vậy, C++ cho phép bạn làm điều trên, ngay cả khi T xảy ra bằng int. Standard thánh nói trong 12.4 p15:

The notation for explicit call of a destructor can be used for any scalar type name. Allowing this makes it possible to write code without having to know if a destructor exists for a given type.

Sự khác biệt giữa việc sử dụng một int đồng bằng và một int typedef'ed là họ là cú pháp thứ khác nhau. Quy tắc là, trong lệnh gọi hàm hủy, điều sau ~ là tên kiểu. int không phải là một điều như vậy, nhưng một typedef-name là. Tra cứu nó trong 7.1.5.2.

+13

+1 cho "The Holy Standard". – ApprenticeHacker

+0

Tôi nghĩ rằng đây là những gì làm cho std :: is_destructible nên không phù hợp trong các trình biên dịch cũ (2012-2014) – GameDeveloper

+0

Không thể bỏ phiếu đủ câu trả lời này! – Nils