Tôi muốn có một sự hiểu biết tốt hơn khi trình biên dịch sẽ ngầm nhanh chóng một thành viên chức năng mẫu.C++ Implicit instantiation của các thành viên chức năng mẫu
Hãy xem xét ví dụ sau:
// example.h
struct Parent {
virtual void foo(double) {}
};
struct Child : Parent {
void foo(double d) { bar(d); }
template<typename T> void bar(T);
virtual void baz();
};
// example.cpp
#include "example.h"
template <typename T>
void Child::bar(T) {}
void Child::baz() {}
Biên dịch này với [g++|clang++] -c example.cpp
, cả GCC và kêu vang ngầm nhanh chóng các chức năng template Child::bar<double>
. Tuy nhiên, những thay đổi dường như nhỏ sau ngăn chặn điều này:
- Làm
foo
không ảo - Làm
Child
không kế thừa từParent
- Loại bỏ
baz
- Làm
baz
không ảo - Xác định
baz
với việc kê khai trong tiêu đề
Có bất kỳ giải thích hợp lý nào ngắn gọn về thời điểm diễn ra sự diễn đạt ngầm định hay không, tôi có cần phải lướt qua một bản sao của tiêu chuẩn không? Tôi đã tìm kiếm SO cho các câu hỏi khác liên quan đến instantiation ngầm, nhưng không tìm thấy nhiều. Tôi tìm thấy gần nhất là this question, nhưng đó là về các hàm ảo trong các mẫu lớp (không phải là các mẫu hàm thành viên).
Để rõ ràng: Tôi hiểu rằng vấn đề này có thể tránh được bằng cách bao gồm định nghĩa trong tiêu đề hoặc mô tả rõ ràng các mẫu mà tôi cần. Điều này chỉ đơn thuần là phát sinh như một điểm tò mò khi đào sâu vào lý do tại sao một lớp (mà tôi đã vô tình bỏ qua những khoảnh khắc rõ ràng) dù được biên soạn và liên kết một cách vui vẻ.
Đơn giản của nó - chúng được khởi tạo chỉ khi được gọi. Tập hợp các trường hợp khác nhau mà bạn có chỉ quyết định khi tham chiếu đó thực sự trở nên cần thiết. Khi bạn có một hàm ảo, nó cần tạo một mục nhập trong bảng ảo. Thanh gọi bên trong foo đang buộc nó o khởi tạo nó. Không có baz, nó cần một vtable cho Child. Làm baz inline không ảnh hưởng đến nó - thats có lẽ kết quả của một tối ưu hóa? Nếu bạn thừa kế một cháu từ con và cho nó một func ảo - BÂY GIỜ nội tuyến không nên ngăn chặn instantiation – excalibur