2010-03-06 25 views
13

Mã sau hoạt động với Visual Studio 2008 nhưng không phải với GCC/G ++ 4.3.4 20090804. Hành vi nào là - theo tiêu chuẩn C++ - chính xác ?GCC/VS2008: Hành vi khác nhau của hàm gọi khi lớp cơ sở templated bắt nguồn từ chính nó

template <int N> 
struct A : A<N-1> {}; 

template <> 
struct A<0> {}; 

struct B : A<1> {}; 

template <int N> 
void Func(const A<N> &a) {} 

int main() 
{ 
    A<1> a; //is derived from A<0> 
    Func(a); //vs2008: ok, g++: ok 
       //Comeau: ok 

    B b;  //is derived from A<1> 
    Func(b); //vs2008: ok, g++: error, no matching function for call to Func(B&) 
       //Comeau: error: no instance of function template "Func" matches the 
       //  argument list. The argument types that you used are: (B). 

    return 0; 
} 

Nếu tôi quá tải Func() với

void Func(const A<0> &a) { std::cout << '0'; } 
void Func(const A<1> &a) { std::cout << '1'; } 

lúc nào cũng là một thứ hai được gọi là (như mong đợi). Vì vậy, tôi cũng sẽ mong đợi các chức năng templated được gọi với N = 1 vì A < 1> là cơ sở trực tiếp của B. Giả định này thực sự sai?

+5

Không biên dịch bằng Comeau Online. Bạn mong đợi gì ở trường hợp thứ hai (vì b có thể chuyển đổi thành A <1> và A <0>)? – UncleBens

+0

Tôi nghĩ rằng đó chỉ là một phần mở rộng MSVC++ khác. –

+0

@UncleBens, wow tôi đã không thấy rằng 'B' cũng thừa kế' A <0> '!Mắt tốt :) –

Trả lời

4

Sau khi một số đào bới N3035, tôi thấy điều này trong phần 14.9.2.1.4:

Nếu P là một lớp học và P có dạng đơn giản-template-id, thì chuyển đổi A có thể là một dẫn xuất lớp của suy luận A. Tương tự như vậy, nếu P là một con trỏ đến một lớp của mẫu đơn giản-mẫu-id, A chuyển đổi có thể là một con trỏ đến một lớp dẫn xuất được chỉ ra bởi suy luận A.

Tuy nhiên, trong 14.9.2.1.5, nó cho biết:

Các lựa chọn thay thế này chỉ được xem xét nếu loại khấu trừ nếu không sẽ thất bại. Nếu họ mang lại nhiều hơn A có thể suy ra A, loại khấu trừ thất bại.

Đó là trường hợp: cả hai A<1>A<0> được coi là lớp cơ sở cho B.

Tôi đoán điều này có nghĩa là không cho Visual Studio (ít nhất, nếu tiêu chuẩn hiện tại nói giống nhau: tập thể dục cho người đọc).

+0

+1 cho việc đào bới :) – neuro

0

Trong ISO/IEC 14882 đó là gần như nhau (14.8.2.1):

  • Nếu P là một lớp học, và P có dạng template-id, sau đó A có thể là một lớp được thừa kế của A. suy luận Tương tự như vậy, nếu P là một con trỏ tới một lớp của mẫu template-id, A có thể là một con trỏ đến một lớp được thừa kế chỉ để bởi A. suy luận

những altenatives là c chỉ được áp dụng nếu khấu trừ loại nếu không sẽ không thành công. Nếu họ thu được nhiều hơn một khoản có thể được suy ra A, thì khoản khấu trừ loại không thành công.

Vì vậy, tôi đồng ý với Jan. Bất kỳ ai ở đây không?

+0

Điều gì có thể là lý do mà nó được chỉ định theo cách này? – user287715

Các vấn đề liên quan