2011-01-03 27 views
6

Đoạn mã sau đây làm việc cho tôi:mẫu Member chức năng và điều hành quá tải() trong C++

class Foo { 
public: 
    template <class T> T& get() { ... } 
}; 

Foo foo; 
foo.get<int>() = ...; 

Tuy nhiên, đoạn mã sau đây không làm việc cho tôi:

class Foo { 
public: 
    template <class T> T& operator()() { ... } 
}; 

Foo foo; 
foo<int>() = ...; 

Các lỗi là:

expected primary-expression before '>' token 
expected primary expression before ')' token 

Cả hai lỗi đều đề cập đến foo<int>()

Tại sao tính năng này không hoạt động và có thể sửa lỗi này không?

+1

Toán tử 'template()' của mẫu của bạn là khá không thể sử dụng được, vì các instantiations của nó sẽ quá tải trên giá trị trả về chỉ. Tiếp tục sử dụng tên 'get' hoặc tương tự. – aschepler

+0

Nó không phải là không sử dụng được (mặc dù nó có thể không được ưa thích). Xem các câu trả lời dưới đây. –

+0

Tại sao bạn templatizing các chức năng nhưng không phải là lớp học như một toàn thể? –

Trả lời

10

Nếu bạn cần phải xác định một cách rõ ràng mẫu đối số, bạn sẽ cần phải sử dụng operator cú pháp:

foo.operator()<int>() 

Không có cách nào để xác định các đối số bằng cách sử dụng cú pháp chức năng gọi. Nếu bạn không thể suy ra các đối số mẫu từ các đối số cho hàm, thì tốt hơn nên sử dụng hàm thành viên hơn là một toán tử quá tải.

+0

Ahh, quả thật vậy, cảm ơn. Nó có ý nghĩa bây giờ. – Dan

-1

Hoặc bạn có thể làm điều này

class Foo { 
public: 
    template <class T> operator T&() { ... } 
}; 

Sau đó, nó sẽ tự động gọi hàm phải phụ thuộc vào sự "trở lại" type:

Foo foo; 
int i=foo; 

Tôi biết rằng hầu hết mọi người không thích điều này như hàm được gọi phụ thuộc vào kiểu trả về, nhưng tôi thấy nó là một "thủ thuật" tuyệt vời thường làm sạch cú pháp.

+3

Cảnh báo bổ sung: Sẽ dễ dàng vô tình khởi tạo phương thức "chuyển đổi" đó với loại không mong muốn. – aschepler

+2

Tôi nghĩ rằng đây là một thủ thuật làm mã phức tạp. Bạn đã cung cấp toán tử chuyển đổi cho loại * bất kỳ * nào đó ... nó sẽ đánh bạn ở hầu hết các địa điểm mà bạn không thể mong đợi hoặc thậm chí không nhận ra nó! –

1

Vấn đề là danh sách tham số mẫu của bạn ở sai vị trí; nó giống như bạn đang cố gắng sử dụng một đối tượng hoặc hàm có tên là foo với đối số mẫu int, nhưng trên thực tế nó là operator() mà bạn muốn danh sách tham số mẫu.

Thật không may (cho là như vậy, ít nhất), không có cách nào xung quanh điều này với các toán tử. Bạn phải gọi cho họ là đầy đủ chức năng:

class Foo { 
public: 
    template <class T> T& operator()() { ... } 
}; 

Foo foo; 
foo.operator()<int> = ...; 

Hy vọng điều này sẽ hữu ích.