2013-10-28 21 views
54

Điều này vừa xuất hiện trong ngữ cảnh another question.Điều gì có nghĩa là "sử dụng ODR" một cái gì đó?

Rõ ràng các hàm thành viên trong các mẫu lớp chỉ được khởi tạo nếu chúng được sử dụng ODR. Ai đó có thể giải thích chính xác điều đó có nghĩa là gì. wikipedia article on One Definition Rule (ODR) không đề cập đến "ODR-use".

Tuy nhiên tiêu chuẩn định nghĩa nó như

Một biến có tên xuất hiện như một biểu hiện khả năng đánh giá lại là ODR-sử dụng trừ khi nó là một đối tượng thỏa mãn các yêu cầu về xuất hiện trong một biểu thức hằng (5.19) và tỷ lệ chuyển đổi từ giá trị sang tỷ lệ (4.1) được áp dụng ngay lập tức.

trong [basic.def.odr].

Chỉnh sửa: Rõ ràng đây là phần sai và toàn bộ đoạn chứa nhiều định nghĩa cho những thứ khác nhau. Đây có thể là một trong những phù hợp cho chức năng lớp mẫu thành viên:

Một chức năng không bị quá tải mà tên tuổi xuất hiện như một biểu hiện khả năng đánh giá lại hoặc một thành viên của một tập hợp các ứng cử viên chức năng, nếu được lựa chọn bởi độ phân giải quá tải khi được gọi từ một biểu thức có thể đánh giá có khả năng được đánh giá là , trừ khi nó là một hàm ảo tinh khiết và tên của nó không đủ điều kiện.

Tôi chưa hiểu, quy tắc này hoạt động như thế nào trên nhiều đơn vị biên dịch? Tất cả các hàm thành viên có được khởi tạo nếu tôi khởi tạo một mẫu lớp một cách rõ ràng không?

+1

Lưu ý rằng [basic.def.odr]/6 áp dụng cho các hàm thành viên của các mẫu lớp" Có thể có nhiều hơn một định nghĩa [...] " – dyp

+2

*" Tất cả các hàm thành viên đều được khởi tạo nếu tôi nhanh chóng khởi tạo một mẫu lớp? "* Có, hãy xem [temp.explicit]/8 + 9 – dyp

Trả lời

48

Nó chỉ là một định nghĩa tùy ý, được sử dụng theo tiêu chuẩn để chỉ định khi bạn phải cung cấp định nghĩa cho một thực thể (như phản đối chỉ là một tuyên bố). Tiêu chuẩn không chỉ nói "đã sử dụng", bởi vì điều này có thể được diễn giải đa dạng tùy theo ngữ cảnh . Và một số ODR-sử dụng không thực sự tương ứng với những gì một trong những thường sẽ kết hợp với "sử dụng"; ví dụ: chức năng ảo luôn được sử dụng ODR trừ khi nó là thuần túy, ngay cả khi nó không phải là thực sự được gọi ở bất kỳ đâu trong chương trình.

Định nghĩa đầy đủ nằm trong §3.2, đoạn thứ hai, mặc dù điều này chứa tham chiếu đến các phần khác để hoàn thành định nghĩa .

Đối với các mẫu, ODR được sử dụng chỉ là một phần của câu hỏi; phần khác là instantiation. Cụ thể, §14.7 bao gồm khi một mẫu được khởi tạo. Nhưng cả hai có liên quan: trong khi văn bản trong §14.7.1 (diễn giải ngầm) là khá dài, nguyên tắc cơ bản là mẫu sẽ chỉ được khởi tạo nếu nó được sử dụng và trong ngữ cảnh này, được sử dụng có nghĩa là ODR- đã sử dụng. Do đó, một chức năng thành viên của một mẫu lớp sẽ chỉ được khởi tạo nếu nó được gọi, hoặc nếu nó là ảo và bản thân lớp đó là được khởi tạo.Các tiêu chuẩn riêng của mình đếm về vấn đề này trong nhiều nơi: các std::list<>::sort sử dụng < trên yếu tố cá nhân, nhưng bạn có thể tạo một danh sách trên một loại nguyên tố mà không hỗ trợ <, miễn là bạn đừng gọi sort trên nó.

+7

Được thăng hạng: Tôi thích ví dụ về' std :: list <> :: sort'. –

2

Trong từ đơn giản, odr-được sử dụng có nghĩa là một cái gì đó (biến hoặc chức năng) được sử dụng trong một bối cảnh mà định nghĩa của nó phải có mặt.

ví dụ:

struct F { 
    static const int g_x = 2; 
}; 

int g_x_plus_1 = F::g_x + 1; // in this context, only the value of g_x is needed. 
          // so it's OK without the definition of g_x 

vector<int> vi; 
vi.push_back(F::g_x);  // Error, this is odr-used, push_back(const int & t) expect 
          // a const lvalue, so it's definition must be present 

Lưu ý, các push_back trên thông qua trong MSVC 2013, hành vi này không phải là tiêu chuẩn tuân thủ, cả hai gcc 4.8.2 và 3.8.0, kêu vang thất bại, thông báo lỗi là: tài liệu tham khảo không xác định thành `K :: g_x '

+0

Có thể odr-sử dụng một thành viên dữ liệu tĩnh như 'vi.push_back (F :: g_x);' trong C++? –

+0

Nhưng giá trị rvalue cũng có thể được chuyển tới 'const int &'? Thành phần const tĩnh có bị ragarded như rvalue không? – bigxiao

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