2016-03-22 16 views
11

Vì vậy, câu hỏi của tôi rất đơn giản:Nhà xây dựng/chuyển nhượng mặc định có bị làm phiền bởi noexcept hoặc constexpr không?

Có bất kỳ điểm nào trong việc chỉ định hàm tạo lớp mặc định là noexcept hoặc constexpr (hoặc bất kỳ thứ gì khác bạn có thể làm)?

struct foo 
{ 
    foo() = default; 
    // vs 
    constexpr foo() noexcept = default; 

    // same thing would apply for copy/move ctors and assignment operators 
}; 

Hai hành vi có giống nhau không?

Điều đó có phụ thuộc vào việc lớp học có phải là POD không? Ví dụ với ví dụ trên cả hai sẽ hoạt động theo cùng một cách, trong khi nếu ví dụ tôi có một thành viên riêng std::vector<int> v = { 1, 2, 3, 4 }; sử dụng phân bổ trong lớp, foo() = default; theo mặc định không phải là noexcept và không phải là constexpr.

Bằng cách viết foo() = default; trình biên dịch chỉ chọn phiên bản tốt nhất: noexcept nếu có thể và constexpr nếu có thể, v.v.

Tôi hy vọng câu hỏi là rõ ràng!

Trả lời

13

[dcl.fct.def.default]/2-3:

2 Một chức năng rõ ràng-defaulted mà không được định nghĩa là xóa có thể được khai báo constexpr chỉ khi nó có thể đã được tuyên bố ngầm như constexpr. Nếu một hàm là một cách rõ ràng vỡ tuyên bố đầu tiên của nó,

  • nó mặc nhiên được coi là constexpr nếu việc khai báo ngầm định, và,
  • nó có đặc điểm kỹ thuật ngoại lệ tương tự như thể nó đã được tuyên bố ngầm ([except.spec]).

3 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 không tương thích ([except.spec]) với đặc tả ngoại lệ của việc kê khai ngầm, sau đó

  • nếu hàm được đặt 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.

Nói cách khác, foo() = default;, mà nhất thiết phải là tuyên bố đầu tiên của constructor mặc định foo 's, sẽ là "constexpr nếu có thể" và "noexcept nếu có thể". Viết rõ ràng constexprnoexcept vẫn hữu ích; nó có nghĩa là "hét lên với tôi nếu nó không thể là constexpr/noexcept".

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