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
Nguồn
2016-04-12 13:06:54
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