xem xét như sau:Template alias tầm nhìn trong lớp lồng nhau
template<typename X>
struct Z {};
struct A
{
using Z = ::Z<int>;
struct B : Z
{
using C = Z;
};
};
này biên dịch tốt. Tốt đẹp. Nhưng bây giờ thêm tham số khác trong Z
:
template<typename X, typename Y>
struct Z {};
struct A
{
template<typename X>
using Z = ::Z<X, int>;
struct B : Z<B>
{
using C = Z<B>; // error: too few template arguments for class template 'Z'
};
};
Ok, có lẽ nó có ý nghĩa rằng định nghĩa của mẫu alias Z
trong lớp A
có thể nhìn thấy khi thừa kế lồng lớp B
, nhưng không phải bên trong cơ thể của nó, gây ra các lỗi kể từ khi định nghĩa toàn cầu của Z
có hai tham số.
Nhưng lý do tại sao là hành vi khác trong trường hợp đầu tiên, khi Z
chỉ là bí danh loại trong A
?
Cuối cùng, hãy A
mẫu:
template<typename X, typename Y>
struct Z {};
template<typename T>
struct A
{
template<typename X>
using Z = ::Z<X, int>;
struct B : Z<B>
{
using C = Z<B>;
};
};
Bây giờ lỗi đã biến mất. Tại sao?
(Thử nghiệm trên Clang 3.6 và GCC 4.9.2)
Wow. Điều này khá rõ ràng, cảm ơn. Lỗi thực sự xuất hiện khi 'A' dừng lại là một mẫu, mà tôi nghĩ sẽ đơn giản hóa mã rất nhiều. Tuy nhiên, bây giờ tôi buộc phải sử dụng hai tên khác nhau cho hai chữ cái 'Z', điều này chỉ làm cho mã trở nên xấu hơn. Nếu có cách giải quyết nào tốt hơn, vui lòng cho tôi biết. – iavr
@iavr Điều gì về 'sử dụng C = Z;'? (Sẽ không hoạt động cho 'A' là mẫu) – Columbo
Bây giờ điều đó thật ấn tượng :-) Có, nó hoạt động trên mã được đơn giản hóa ở đây, nhưng không hoạt động trên mã gốc của tôi (' unknown type name 'Z''). Tôi sẽ phải kiểm tra sự khác biệt ở đâu. 'A' không phải là một mẫu nữa, và tôi dự định giữ nó theo cách đó. – iavr