2015-04-07 19 views
12

Mã:Chương trình với "noexcept" constructor chấp nhận bởi gcc, bị từ chối bởi kêu vang

struct T { T() {} }; 

struct S 
{ 
    T t; 

    S() noexcept = default; 
}; 

int main() 
{ 
// S s; 
} 

g ++ 4.9.2 chấp nhận này không có lỗi hoặc cảnh báo, tuy nhiên Clang 3.6 và 3.7 báo cáo cho dòng 7:

error: exception specification of explicitly defaulted default constructor does not match the calculated one 

Tuy nhiên, nếu dòng S s; không nhận xét ra, g ++ 4.9.2 giờ đây báo cáo:

noex.cc: In function 'int main()': 
noex.cc:12:7: error: use of deleted function 'S::S()' 
    S s; 
    ^
noex.cc:7:5: note: 'S::S() noexcept' is implicitly deleted because its exception-specification does not match the implicit exception-specification '' 
    S() noexcept = default; 
    ^

Trình biên dịch nào phù hợp với mã gốc?


Bối cảnh:

g ++ thậm chí cho phép sau đây để được thêm vào main:

std::cout << std::is_constructible<S>::value << '\n'; 

mà kết quả đầu ra 0. Tôi gặp phải vấn đề này khi sử dụng clang để biên dịch một số mã phức tạp đã sử dụng nhiều mẫu, SFINAE và không nhận dạng. Trong mã đó ST là các lớp mẫu; do đó, hành vi phụ thuộc vào loại S được khởi tạo với. Clang từ chối nó với lỗi này cho một số loại, trong khi g ++ cho phép nó và SFINAE hoạt động dựa trên is_constructible và các đặc điểm tương tự.

+0

Bởi vì trong S constructor bạn sẽ nhận được cuộc gọi đến T constructor có thể ném bất kỳ exception.Clang là đúng, tôi tin rằng –

+1

@SeverinPappadeux đó là sự thật về ngoại lệ nhưng vấn đề có vẻ là liệu mã có nên bị từ chối ngay lập tức hay không cho dù hiệu ứng của '= default' nên được * xác định là xóa * mà g + + có vẻ là làm. –

Trả lời

15

Phụ thuộc vào phiên bản tiêu chuẩn bạn đang tư vấn.

N3337 [dcl.fct.def.default]/p2:

Một chức năng rõ ràng-defaulted [...] có thể có một rõ ràng ngoại lệ đặc điểm kỹ thuật chỉ khi nó là tương thích (15,4) với thông số ngoại lệ đặc biệt về khai báo ngầm.

làm cho mã ban đầu của bạn không đúng định dạng.

này được thay đổi bằng cách CWG issue 1778 đọc (N4296 [dcl.fct.def.default]/p3):

Nếu một chức năng mà được mặc định một cách rõ ràng được khai báo với một ngoại lệ đặc điểm kỹ thuật rằng không tương thích (15.4) với đặc tả ngoại lệ trên khai báo ngầm, sau đó

  • nếu hàm này được mặc định rõ ràng trên khai báo đầu tiên, nó được định nghĩa là đã xóa;
  • nếu không, chương trình không đúng định dạng.

có nghĩa là hàm tạo hiện chỉ được xác định là đã xóa. (Các từ ngữ trên kết hợp các thay đổi được thực hiện bởi N4285, một bài sau C + + 14 làm cho một số thay đổi dọn dẹp nhằm mục đích là hoàn toàn biên tập. Phiên bản N3936 là hoàn toàn giống nhau.)

Có lẽ GCC thực hiện độ phân giải của CWG1778, trong khi Clang thì không.

+0

Phiên bản nào xuất hiện trong C++ 14 đã xuất bản? (clang 3.7 vẫn từ chối mã với -std = C++ 14) –

+0

@MattMcNabb Vấn đề này có trạng thái "C++ 14", vì vậy phiên bản thứ hai phải ở trong C++ 14. Lưu ý rằng đây là một DR, vì vậy nó có thể sẽ được thực hiện ngay cả trong chế độ C++ 11. –

+0

@MattMcNabb 4296 là khá nhiều những gì đã được bình chọn là C++ 14 modulo typos và như vậy –

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