2015-05-10 32 views
13

[basic.def.odr]/3 làm cho một tham chiếu đến thuật ngữ "nontrivial function", có định nghĩa mà tôi không thể tìm thấy trong tiêu chuẩn (N4140).Chức năng tầm thường là gì?

[basic.def.odr]/3

A x biến có tên xuất hiện như một biểu hiện khả năng đánh giá lại cũ được ODR-sử dụng bởi cựu trừ khi áp dụng vế trái-to-rvalue chuyển đổi (4.1) đến x tạo ra một biểu thức liên tục (5.19) không gọi hàm bất kỳ hàm phi nong nào và nếu x là một đối tượng, thì ex là một phần tử của tập hợp các kết quả tiềm năng của một biểu thức e, trong đó lvalue-to -giá trị chuyển đổi giá trị (4.1) được áp dụng cho e, hoặc e là một biểu thức giá trị bị loại bỏ (khoản 5) là .

Trả lời

8

"chức năng không tầm thường" là bổ sung cho "chức năng thành viên đặc biệt tầm thường". Có các định nghĩa cho một hàm tạo mặc định và không bình thường/sao chép/di chuyển, toán tử gán/di chuyển sao chép/di chuyển là - các đặc điểm chỉ áp dụng cho các hàm thành viên đặc biệt và quyết định xem ví dụ những điều này cần phải được gọi trong một số trường hợp nhất định.

Các định nghĩa cho chúng có thể được tìm thấy trong chương §12.

constructor mặc định, §12.1/4:

Một constructor mặc định là tầm thường nếu nó không phải là người dùng cung cấp và nếu:

  • lớp của nó không có chức năng ảo (10.3) và không có lớp cơ sở ảo (10.1) và
  • không có thành viên dữ liệu không tĩnh nào trong lớp của nó có bộ khởi tạo dấu ngoặc đơn hoặc bằng nhau và
  • tất cả các lớp cơ sở trực tiếp của lớp của nó có các hàm tạo mặc định nhỏ, và
  • cho tất cả các thành viên dữ liệu không tĩnh thuộc loại lớp (hoặc mảng của chúng), mỗi lớp như vậy có một hàm tạo mặc định tầm thường .

Nếu không, hàm tạo mặc định là không tầm thường.

constructors Sao chép/di chuyển, §12.8/12:

Một bản sao/di chuyển constructor cho lớp X là tầm thường nếu nó không phải là dùng cung cấp, nó tham số kiểu -list tương đương với thông số kiểu danh sách của tuyên bố ngầm và nếu

  • lớp X không có chức năng ảo (10.3) và không có lớp cơ sở ảo (10.1), và
  • lớp X không có thành viên dữ liệu tĩnh không của biến động có trình độ loại, và
  • các nhà xây dựng được lựa chọn để sao chép/di chuyển mỗi lớp cơ sở subobject trực tiếp là tầm thường, và
  • cho mỗi không tĩnh thành viên dữ liệu của X thuộc loại lớp (hoặc mảng của chúng), hàm tạo được chọn để sao chép/di chuyển thành viên đó là tầm thường;

nếu không thì trình tạo bản sao/di chuyển là không tầm thường.

Sao chép/di chuyển phân công điều hành, §12.8/26:

Một nhiệm vụ điều hành sao chép/di chuyển cho lớp Xtầm thường nếu nó là không dùng cung cấp, thông số của nó -type-list tương đương với thông số kiểu danh sách của tuyên bố ngầm và nếu

  • lớp X không có chức năng ảo (10,3) và không có lớp cơ sở ảo (10.1), và
  • lớp X không có thành viên dữ liệu tĩnh không của biến động có trình độ loại, và
  • toán tử gán được lựa chọn để sao chép/di chuyển mỗi lớp cơ sở trực tiếp
  • cho mỗi thành viên dữ liệu không tĩnh của X thuộc loại lớp (hoặc mảng của chúng), toán tử gán được chọn để sao chép/di chuyển thành viên là không đáng kể;

nếu không nhà điều hành gán bản sao/di chuyển là không tầm thường.

Destructor, §12.4/5:

Một destructor là tầm thường nếu nó không phải là người dùng cung cấp và nếu:

  • destructor không phải là ảo,
  • tất cả các lớp cơ sở trực tiếp của lớp học có các trình phá hủy tầm thường và
  • cho tất cả các thành viên dữ liệu không tĩnh của lớp của nó thuộc loại lớp (hoặc mảng của chúng), mỗi lớp như vậy có một hàm hủytầm thường.

Nếu không, destructor là nontrivial

+2

Tôi chỉ đang cố hiểu lý do cho cụm từ "chức năng tầm thường" được sử dụng trong [basic.def.odr]/3. Bạn có thể đưa ra một ví dụ trong đó một đối tượng ** không đổi ** của một lớp sẽ được coi là ** odr-used **, khi gọi một hàm thành viên không tầm thường, tức là, một hàm tạo non-tầm thường, hoặc một không tầm thường destructor, hoặc một nhà điều hành chuyển nhượng copy-move không tầm thường? – Belloc

0

Có thể ví dụ nhỏ này sẽ giúp bạn hiểu được chức năng không tầm thường trong bối cảnh [basic.def.ODR]/3

struct C { 
     int l; 
     constexpr C(int _l) : l(_l) { } 
     constexpr C(const C&c) : q(c.l* 2) { } 
     }; 

     int main(void) { 
     constexpr C c(42); 
     constexpr int m= c.l; 
     struct K{ 
     int foo() { return c.l; } 
     } l; 
     return l.foo(); 
     } 

Nếu Bạn nhìn vào dòng follwowing trong tiêu chuẩn

áp dụng việc chuyển đổi giá trị trái-to-rvalue (4.1) để x mang lại một biểu thức hằng số (5,19) mà không gọi bất kỳ chức năng không tầm thường

đây c thỏa mãn các yêu cầu về xuất hiện trong một biểu thức hằng số, nhưng áp dụng việc chuyển đổi giá trị trái-to-rvalue đến một gọi một hàm không tầm thường .

Tại sao nó gọi một chức năng không tầm thường?

Khi chuyển đổi lvalue-to-rvalue xảy ra trong toán hạng chưa được đánh giá hoặc biểu thức con mà giá trị chứa trong đối tượng được tham chiếu không được truy cập. Nếu không, nếu glvalue có loại lớp, bản sao chuyển đổi sẽ khởi tạo tạm thời loại T từ glvalue và kết quả của chuyển đổi là giá trị tạm thời cho tạm thời

Vì vậy, giá trị được tạo bằng cách sử dụng hàm tạo bản sao của lớp C và kể từ khi nhà xây dựng Sao chép được người dùng khai báo, Nó là không tầm thường và do đó c không phải là ODR được sử dụng ở đây

Toán tử gán sao chép/di chuyển cho lớp X là tầm thường nếu nó không được người dùng cung cấp, tham số của nó -loại-danh sách tương đương với danh sách loại tham số của khai báo tiềm ẩn

Tôi hy vọng ví dụ này sẽ làm rõ y nghi ngờ của chúng tôi

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