Với đoạn mã sau:Moving Template Method để Breaks phái sinh Compilation
template<typename T>
class A
{
public:
T t;
};
class B
{
public:
void foo(int i) {}
template<typename T>
void foo(A<T>& a) {}
};
int main()
{
A<int> a;
B b;
b.foo(a );
b.foo(a.t);
}
này biên dịch và hoạt động tốt; các phiên bản quá tải chính xác của B::foo()
được chọn và được gọi là a
và a.t
.
Bây giờ tôi giới thiệu một lớp mới C
mà xuất phát từ B
và di chuyển các phiên bản mẫu của ::foo()
ra khỏi B
và thành C
:
template<typename T>
class A
{
public:
T t;
};
class B
{
public:
void foo(int i) {}
};
class C: public B
{
public:
template<typename T>
void foo(A<T>& a) {}
};
int main()
{
A<int> a;
C c;
c.foo(a ); // Fine
c.foo(a.t); // Error
}
Và bây giờ mã sẽ không biên dịch nữa. Visual Studio 2005 được nêu:
error C2784: 'void C::foo(A<T> &)' : could not deduce template argument for 'A<T> &' from 'int'
Trong thực tế, gọi C::foo()
với bất kỳ int
kết quả giá trị do lỗi này. Nó gần như có vẻ như quá tải phương thức cho int
đang bị ẩn bởi quá tải mẫu.
Tại sao điều này lại xảy ra? Có một số vấn đề với trình biên dịch Visual Studio 2005? Thật không may, tôi không thể kiểm tra nó trên bất kỳ trình biên dịch khác ngay bây giờ.
Mọi thông tin đều được đánh giá cao.