2013-02-23 30 views
11

Tôi không chắc chắn nếu nó là lỗi trong Clang 3.2 hoặc vi phạm C++ 03, nhưng có vẻ như việc khởi tạo rõ ràng các hàm tạo khuôn mẫu cho các lớp mẫu không thành công. các hàm thành viên của các lớp mẫu thành công.Sự khởi tạo rõ ràng của hàm tạo khuôn mẫu cho lớp mẫu

Ví dụ, biên dịch sau đây mà không có một vấn đề với cả hai kêu vang ++ và g ++:

template<typename T> 
class Foo 
{ 
public: 
    template<typename S> 
    void Bar(const Foo<S>& foo) 
    { } 
}; 
template class Foo<int>; 
template class Foo<float>; 

template void Foo<int>::Bar(const Foo<int>& foo); 
template void Foo<int>::Bar(const Foo<float>& foo); 
template void Foo<float>::Bar(const Foo<int>& foo); 
template void Foo<float>::Bar(const Foo<float>& foo); 

trong khi biên dịch sau đây mà không cảnh báo với g ++ nhưng không thành công với kêu vang ++:

template<typename T> 
class Foo 
{ 
public: 
    template<typename S> 
    Foo(const Foo<S>& foo) 
    { } 
}; 
template class Foo<int>; 
template class Foo<float>; 

template Foo<int>::Foo(const Foo<int>& foo); 
template Foo<int>::Foo(const Foo<float>& foo); 
template Foo<float>::Foo(const Foo<int>& foo); 
template Foo<float>::Foo(const Foo<float>& foo); 

Đặc biệt, tôi thấy hai thông báo lỗi của biểu mẫu:

TemplateMember.cpp:12:20: error: explicit instantiation refers to member 
     function 'Foo<int>::Foo' that is not an instantiation 
template Foo<int>::Foo(const Foo<int>& foo); 
       ^
TemplateMember.cpp:9:16: note: explicit instantiation refers here 
template class Foo<int>; 
      ^

Đây có phải là vi phạm không tiêu chuẩn hoặc lỗi trong clang ++?

+3

Hình như C++ 03 hợp lệ. Có lẽ lỗi trong Clang ++ –

Trả lời

5

Dường như bạn đã tìm thấy lỗi GCC. Những tên cả các bản sao constructor ngầm-tuyên bố:

template Foo<int>::Foo(const Foo<int>& foo); 
template Foo<float>::Foo(const Foo<float>& foo); 

mỗi [temp.explicit] p4,

Nếu việc kê khai của tên instantiation rõ ràng một ngầm-tuyên bố đặc biệt hàm thành viên (khoản 12) , chương trình bị hỏng.

Do đó, Clang là chính xác để từ chối mã này.

+0

Cảm ơn bạn Richard! Bạn hoàn toàn chính xác. Bằng cách khai báo rõ ràng hàm tạo Foo (const Foo & foo) và loại bỏ các instantiations rõ ràng của hàm tạo bản sao, chương trình sau đó biên dịch với Clang. –

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