Lưu ý: Tôi đã xem here và tôi không nghĩ câu trả lời là đúng.Hiển thị ngầm định các mẫu chức năng khi lấy địa chỉ
Các quy tắc điều chỉnh việc diễn giải hàm ngầm tiềm ẩn khi lấy địa chỉ của chúng là gì? 14.7.1/9 của n3242 nói điều này:
An thực hiện sẽ không ngầm nhanh chóng một hàm mẫu, một mẫu thành viên, một hàm thành viên không ảo, một lớp học thành viên, hoặc một thành viên dữ liệu tĩnh của một lớp mẫu mà không yêu cầu instantiation.
Bây giờ, chắc chắn không bắt buộc phải có định nghĩa chức năng để lấy địa chỉ của nó. Chúng ta có thể lấy địa chỉ của các hàm được khai báo về phía trước và có chúng được định nghĩa trong một đơn vị dịch thuật khác.
Đó là trường hợp, tôi không biết khi nào cần thiết. Tuy nhiên, trình biên dịch dường như có ý tưởng riêng của họ. Thử nghiệm trên GCC và VC, dưới đây là một vài ví dụ:
template <typename T> void CallBanana() { T::Banana(); }
template <typename T> void CallUnimpl();
template <typename T>
struct S {
static void CallBanana() { T::Banana(); }
static void CallOrange() { T::Orange(); }
static void CallUnimpl();
};
struct B { static void Banana() {} };
int main() {
(void)(&CallBanana<void>); // 1
(void)(&CallUnimpl<void>); // 2
(void)(&S<void>::CallBanana); // 3
(void)(&S<void>::CallOrange); // 4
(void)(&S<void>::CallUnimpl); // 5
(void)(&S<B>::CallBanana); // 6
}
Chúng nên được nhận xét từng người một để xem hiệu ứng.
GCC 4.7 tested here sẽ khiếu nại khoảng 1, 3 và 4. Vì vậy, nó sẽ khởi tạo tất cả các định nghĩa nếu chúng tồn tại.
VC 2010 (không kiểm tra trực tuyến, xin lỗi) instantiates 3 và 4, nhưng không nhanh chóng 1.
Clang 3,0 tested here có hành vi tương tự như VC 2010.
Không biên dịch phàn nàn về 2 hoặc 5, mà tôi mong đợi. Tôi hy vọng nó sẽ không liên kết nếu tôi thực sự sử dụng những con trỏ mặc dù.
Trên tất cả các trình biên dịch, 6 biên dịch. Tôi mong đợi điều này, nhưng nó được dự định để cho thấy rằng toàn bộ mẫu lớp không được khởi tạo (như được yêu cầu trong câu trả lời cho câu hỏi khác) chỉ vì tôi lấy địa chỉ của một hàm duy nhất. Nếu toàn bộ khuôn mẫu được khởi tạo, thì S :: CallOrange sẽ không biên dịch, vì B không chứa hàm Orange.
Vì vậy, tôi tự hỏi liệu có ai có câu trả lời dứt khoát về hành vi đúng hay không. Tiêu chuẩn này dường như tuyên bố rằng không có hàm nào được khởi tạo, nhưng ba trình biên dịch phổ biến khởi tạo trong một số trường hợp, nhưng khác nhau với nhau.
Tôi hoàn toàn không đồng ý, theo như tôi thấy Tiêu chuẩn yêu cầu chức năng được khởi tạo khi địa chỉ của nó được chụp và tất cả 6 địa chỉ được thực hiện. Nếu không thể khởi tạo hàm (1, 3 và 4) thì lỗi biên dịch sẽ được nâng lên. Vì vậy, tôi sẽ nói rằng 2, 5 và 6 nên được khởi tạo; và kể từ khi địa chỉ của họ được thực hiện (cho dù bạn cast để 'void' là không thích hợp) sự vắng mặt của họ nên kích hoạt một lỗi linker (trừ khi tối ưu hóa). –
'theo như tôi thấy' - ở đâu? Phần và đoạn, xin vui lòng. Các phôi để vô hiệu hóa chỉ đơn giản là để tránh cảnh báo về các biểu thức được sử dụng như báo cáo, không liên quan đến những gì tôi đang làm. – Fuz
Nếu tôi có phần và đoạn, nó sẽ là một câu trả lời;) Tôi tin rằng nó nằm trong trường hợp được sử dụng. –