2016-05-17 27 views
6

Biên dịch trên C++ 03, tôi đã cố gắng viết một hàm mẫu thử trả về hàm con trỏ tới thành viên của hàm thành viên trả về int và nhận hai đối số nổi:Trả về hàm con trỏ thành thành viên (không có typedef)

template<typename TemplateClass> 
int (TemplateClass::*)(float,float) Testtest(TemplateClass &A) 
{ 
    return &TemplateClass::Function; 
} 

Nhưng tự nhiên, bất kể biến thể nào của cú pháp hàm con trỏ thành thành viên tôi sử dụng, trình biên dịch đều than phiền lỗi khởi tạo. Typedef, mặc dù nó hoạt động với các lớp đã biết, vì các lý do rõ ràng (đặt tên xung đột), sẽ không chấp nhận các đối số lớp mẫu cho các lớp mà tôi không thể biết trước khi có khả năng sử dụng cùng một hàm.

Cách non-typedef nào có chức năng này để biên dịch và trả về hàm con trỏ thành thành viên?

Trả lời

5

Để khai báo nó mà không có một loại bí danh, không có loại trừ, và không có một loại dấu sự trở lại:

template<typename TemplateClass> 
int (TemplateClass::* Testtest(TemplateClass &A))(float,float) 

Nhưng tất nhiên đây không phải là những gì bạn sẽ sử dụng trong mã thực. Thay vào đó bạn sẽ sử dụng một alias template:

template<typename T> 
using return_type = int (T::*)(float,float); 

template<typename TemplateClass> 
return_type<TemplateClass> Testtest(TemplateClass &A) 

Hoặc kiểu trả về khấu trừ trong C++ 14:

template<typename TemplateClass> 
auto Testtest(TemplateClass &A) 

Hoặc một loại dấu sự trở lại (trong C++ 11):

template<typename TemplateClass> 
auto Testtest(TemplateClass &A) -> int (TemplateClass::*)(float,float) 
+0

Vâng, tôi chưa bao giờ đoán được câu hỏi đầu tiên. Nó quá ... phức tạp. C + +, tại sao bạn làm điều này ?! – c1646091

+1

@ c1646091 Cú pháp đó được kế thừa từ C. – emlai

+2

C, tại sao bạn làm điều này ?! – c1646091

2
int (Class::*f())(float,float); 

f là chức năng chụp không có đối số trở về con trỏ đến hàm thành viên của lớp Class takinf 2 phao nổi và trở int.

Và mẫu phiên bản:

  template <typename Type> 
     int (Type::*f())(float,float); 
3

Bạn cần mẫu thử nghiệm này:

template<typename TemplateClass> 
int (TemplateClass::*Testtest(TemplateClass &A)) (float,float) { } 
0

Tôi từ chối tiền đề của câu hỏi của bạn. Sử dụng typedefs. Hoặc, cụ thể là một đặc điểm kiểu:

template <class T, class F> 
struct make_mem_fun { 
    typedef F T::*type; 
}; 

template<typename TemplateClass> 
typename make_mem_fun<TemplateClass, int(float, float)>::type 
Testtest(TemplateClass &A) 
{ 
    return &TemplateClass::Function; 
} 

Đó là cách dễ hiểu hơn cú pháp phức tạp thực sự trả về loại. Với C++ 11, chúng ta có thể biến nó thành một bí danh để thả các công cụ typename ::type.

+0

* Tại sao * bạn có từ chối tiền đề của câu hỏi? Typedefs, như đã nói, không làm việc với các mẫu - được chứng minh bằng cách sử dụng một cấu trúc của bạn như một loại công việc xung quanh. Cá nhân tôi muốn biết cú pháp của hàm trả về hàm con trỏ thành thành viên trông như thế nào hơn là chôn lấp sự thiếu hiểu biết của tôi trong một cách giải quyết 'luôn luôn typedef', không chỉ để tôi có thể thực hiện nó, mà tôi có thể cũng xác định nó là tốt. Kiến thức bị chôn vùi rất nhiều ngay cả khi nhiều tìm kiếm không thể khai thác nó, thử nghiệm thất bại và tôi buộc phải hỏi về SO. – c1646091

+0

@ c1646091 Bạn có thể xem lướt qua những gì 'int (TemplateClass :: * Testtest (TemplateClass & A)) (float, float)' nghĩa là gì? Tôi sẽ mất 10 phút để phân tích điều đó. Hiểu được 'make_mem_fun ' nghĩa là gì? Miếng bánh. – Barry

+0

@ c1646091 Và như câu trả lời của tôi cho thấy, typedefs làm việc với các mẫu.Đây là mẫu C++ 03 typedef. Nó trở nên ít chi tiết hơn trong C++ 11, nhưng nó không giống như nó không tồn tại. – Barry

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