2015-07-18 18 views
7

Xem xét việc này (giảm thiểu) ví dụ:Xác định mẫu hàm thành viên out-of-line

template <typename Descriptor> 
class hash_table 
{ 
public: 
    typedef int value_type; 

    template <typename Argument, int Callback (value_type *, Argument)> 
    void traverse (Argument); 

    template <int Callback (value_type *)> 
    void traverse_void(); 
}; 

tôi định nghĩa một lớp mẫu trong đó có chức năng thành viên mẫu với các thông số phi-type. Lưu ý rằng Callback phụ thuộc vào value_type typedef. Bây giờ tôi muốn tự xác định các chức năng:

template <typename Descriptor> 
template <typename Argument, int Callback (typename hash_table <Descriptor>::value_type *, Argument)> 
void hash_table <Descriptor>::traverse (Argument) {} 

template <typename Descriptor> 
template <int Callback (typename hash_table <Descriptor>::value_type *)> 
void hash_table <Descriptor>::traverse_void() {} 

Tôi nhận được lỗi không nhất quán từ trình biên dịch. Kết quả không phụ thuộc vào các tùy chọn, chỉ định phiên bản của tiêu chuẩn C++ (tức là, tương tự cho C++ 98, C++ 11 và C++ 14), nhưng phụ thuộc vào trình biên dịch.

GCC 6.0.0 (thân cây gần đây, cũng như một số phiên bản khác) chấp nhận mã này.

Clang 3.7.0 (thân cây gần đây) cung cấp cho các lỗi sau:

test.cc:18:31: error: out-of-line definition of 'traverse_void' does not match any declaration in 'hash_table<Descriptor>' 
void hash_table <Descriptor>::traverse_void() {} 
           ^~~~~~~~~~~~~ 
1 error generated. 

EDG (Intel C++ Compiler v 15.0.3.) Mang đến cho hai lỗi:

test.cc(15): error: declaration is incompatible with function template "void hash_table<Descriptor>::traverse<Argument,Callback>(Argument)" (declared at line 7) 
    void hash_table <Descriptor>::traverse (Argument) {} 
           ^

test.cc(19): error: declaration is incompatible with function template "void hash_table<Descriptor>::traverse_void<Callback>()" (declared at line 10) 
    void hash_table <Descriptor>::traverse_void() {} 
           ^
compilation aborted for test.cc (code 2) 

là gì mong đợi hành vi (theo tiêu chuẩn)? Nếu mã sai, làm thế nào để sửa các định nghĩa hàm?

Trả lời

1

Mã của bạn có vẻ ổn với tôi, tôi thấy không có lý do gì để nó không biên dịch. Có lẽ là một lỗi trên trình biên dịch không cho phép nó. Tuy nhiên, kể từ khi [temp.param]:

A non-type template-parameter of type “array of T ” or “function returning T ” is adjusted to be of type “pointer to T ” or “pointer to function returning T ”, respectively.

Bạn chỉ có thể chuyển Callback chính mình để trở thành một chức năng con trỏ-to-. Hành vi sẽ giống hệt nhau ở tất cả các khía cạnh, với lợi ích bổ sung mà mã này cũng biên dịch trên clang.

+0

[temp.param]/p8. Có một điều chỉnh tự động tương tự như các thông số chức năng. –

+0

@ T.C. Đó là từ ngữ khủng khiếp sau đó. Điểm liệt kê các loại được phép là gì nếu bạn định bổ sung thêm sau? – Barry

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