Cho mẫu lớp sau:
template<typename T>
struct Outer
{
struct Inner;
auto f(Inner) -> void;
};
chúng tôi xác định Inner
riêng cho từng chuyên ngành của Outer
:
template<>
struct Outer<int>::Inner {};
template<>
struct Outer<double>::Inner {};
và sau đó xác định hàm thành viên f
một lần cho tất cả các chuyên ngành Outer
:
auto Outer<T>::f(Inner) -> void
{
}
nhưng Clang (9.0.0) phàn nàn:
error: variable has incomplete type 'Outer::Inner'
auto Outer<T>::f(Inner) -> void
^
Chúng tôi có thể tránh lỗi trình biên dịch bằng cách cung cấp định nghĩa Inner
cho tất cả các chuyên ngành khác về Outer
:
template<typename T>
struct Outer<T>::Inner {};
hoặc bằng cách định nghĩa f
riêng cho từng chuyên ngành:
template<>
auto Outer<int>::f(Inner) -> void
{
}
template<>
auto Outer<double>::f(Inner) -> void
{
}
Cả GCC và MSVC đều chấp nhận mã ban đầu, điều này đặt ra câu hỏi; Đây có phải là lỗi Clang hay đây là cách thực hiện phù hợp duy nhất trong số ba?
Inner
cho tất cả các chuyên ngành khác và định nghĩa f
riêng cho từng chuyên môn đều giải quyết lỗi biên dịch.
Inner
là được báo cáo là một loại không đầy đủ mặc dù các định nghĩa cho mỗi chuyên ngành Outer
được cung cấp. Rõ ràng Inner
sẽ (chính xác) là một loại không đầy đủ nếu bạn loại bỏ định nghĩa của nó.