2015-03-06 15 views
6

Tôi cố gắng để sử dụng mẫu cho chức năng gọi điều hành quá tải như trong chương trình sau đây:C++ mẫu cho hàm operator gọi

#include <stdio.h> 

struct Apple 
{ 
    template <typename tn> tn value(); 
    template <typename tn> tn operator()(); 
}; 

template <> int Apple::value() 
{ 
    return 10; 
} 

template <> int Apple::operator()() 
{ 
    return 10; 
} 

int main() 
{ 
    Apple apple; 
    printf("Value : %d\n", apple<int>()); 
    printf("Value : %d\n", apple.value<int>()); 
    return 0; 
} 

Trong khi gọi hàm giá trị trong in thứ hai không hiển thị bất kỳ lỗi người điều khiển chức năng cuộc gọi trong bản in đầu tiên hiển thị lỗi expected primary-expression. Tôi không biết mình đang làm gì sai. Bất cứ ai có thể giúp tôi biết vấn đề cảm ơn trước.

Trả lời

10

Vấn đề là khi gọi một templated operator() (dòng thứ hai là main()). Trong trường hợp của bạn, bạn cần phải xác định một cách rõ ràng kiểu trả về, vì nó không thể suy luận, và đúng cách để làm việc đó là:

printf("Value : %d\n", apple.operator()<int>()); 

operator()() là một hàm template thành viên đó mất () như thông số. Vì vậy, tên của nó là operator(), danh sách tham số của nó là (). Do đó, để tham khảo, bạn cần sử dụng apple.operator() (tên của nó), theo sau là <int> (tham số mẫu), sau đó theo sau là () (danh sách tham số). Thay thế tinh thần tên operator() bằng FUNCTION, vì vậy operator()()FUNCTION() và bạn sẽ thấy mẫu. Trong trường hợp của bạn, apple<int>() đang gọi một mẫu không operator()() trên mẫu instantiation apple<int> đối tượng, nghĩa là apple<int>.operator()(), không phải là thứ bạn muốn.

Hữu ích để xác định toán tử như vậy? Có lẽ không, vì nó dẫn đến cú pháp xấu xí.


Bạn có thể đạt được những gì có thể bạn muốn bằng cách sử dụng auto trở lại gõ trong C++ 14, như

#include <stdio.h> 

struct Apple 
{ 
    template <typename tn> tn value(); 
    auto operator()(); 
}; 

template <> int Apple::value() 
{ 
    return 10; 
} 

auto Apple::operator()() // not a template anymore, return type is deduced int 
{ 
    return 10; 
} 

int main() 
{ 
    Apple apple; 
    printf("Value : %d\n", apple()); 
    printf("Value : %d\n", apple.value<int>()); 
    return 0; 
} 

Trong ví dụ này, auto không thực sự tỏa sáng, như bạn bằng tay có thể chỉ định int như kiểu trả về, nhưng trong khai báo phức tạp hơn có thể thực sự hữu ích.

+0

câu trả lời tuyệt vời đã giúp cảm ơn bạn. tôi có thể biết tại sao cuộc gọi không thể được suy ra – Dinesh

+0

@Dinesh, cách duy nhất để trình biên dịch suy ra một loại là khớp với nó với một số biểu thức. Trong trường hợp của bạn, tại trang web cuộc gọi, không có biểu thức nào khớp với. – vsoftco

+0

có nhưng tôi đã xác định rõ ràng loại trong cả hai trường hợp và tôi không thể hiểu tại sao lỗi chỉ trong hàm gọi quá tải của nhà điều hành – Dinesh