2009-02-03 39 views
5

Tôi tự hỏi tại sao mã ví dụ giả mạo sau hoạt động hoàn toàn tốt trong Visual Studio 2005, nhưng tạo ra một lỗi trong GCC ("không có chức năng phù hợp để gọi" khi gọi Interpolate() như hình dưới đây).GCC 4.0: "không có chức năng phù hợp để gọi" trong chức năng mẫu

Ngoài ra, làm cách nào để giải quyết vấn đề này? Dường như thông báo lỗi chỉ là một thông báo chung vì GCC không có thông điệp cụ thể hơn cho lý do thực sự của vấn đề và nó phải xuất ra một thứ gì đó. Tôi là một chút mất mát về làm thế nào để tiến hành porting lớp này mà không có một số cách giải quyết thực sự xấu xí.

namespace Geo 
{ 
    template <class T> 
    class TMyPointTemplate 
    { 
     T X,Y; 
    public: 
     inline TMyPointTemplate(): X(0), Y(0) {} 
     inline TMyPointTemplate(T _X,T _Y): X(_X), Y(_Y) {} 
     inline T GetX()const { return X; } 
     inline T GetY()const { return Y; } 
     //... 
     template<T> TMyPointTemplate<T> Interpolate(const TMyPointTemplate<T> &OtherPoint)const 
     { 
      return TMyPointTemplate((X+OtherPoint.GetX())/2,(Y+OtherPoint.GetY())/2); 
     }   
    }; 
    typedef TMyPointTemplate<int> IntegerPoint; 
} 

Geo::IntegerPoint Point1(0,0); 
Geo::IntegerPoint Point2(10,10); 
Geo::IntegerPoint Point3=Point1.Interpolate(Point2); //GCC PRODUCES ERROR: no matching function for call to 'Geo::TMyPointTemplate<int>::Interpolate(Geo::IntegerPoint&)' 

Nhờ sự giúp đỡ của bạn,

Adrian

Trả lời

9

Tôi không nghĩ rằng bạn cần mẫu có ở tất cả trong định nghĩa chức năng, vì nó được định nghĩa inline với lớp

TMyPointTemplate Interpolate(const TMyPointTemplate &OtherPoint)const { 

nên làm.

Và khi bạn sử dụng mẫu để xác định hàm không trực tuyến, tôi nghĩ bạn cần từ khóa lớp trong đó như thế này.

template<class T> // <- here 
TMyPointTemplate<T> TMyPointTemplate<T>::Interpolate(const TMyPointTemplate<T> &OtherPoint)const { 
+0

Câu trả lời hay. Cảm ơn sự giúp đỡ của bạn! :-) –

9

Evan's answer giải quyết vấn đề, nhưng tôi nghĩ có thể hữu ích khi giải thích lý do.

Như được viết, Nội suy là hàm mẫu thành viên với một tham số mẫu không phải là 'không kiểu mẫu' (thay vì tham số mẫu kiểu gần như chắc chắn là những gì bạn dự định). Để hiển thị này, chúng tôi có thể cung cấp thông số mà một cái tên:

template<T t> TMyPointTemplate<T> Interpolate 
     (const TMyPointTemplate<T> &OtherPoint)const 

Và bây giờ chúng ta có thể thấy làm thế nào để gọi chức năng đó, chúng tôi chỉ cần cung cấp một giá trị cho 't':

Geo::IntegerPoint Point3=Point1.Interpolate <0> (Point2); 

Thêm lớp hoặc tên tệp trước 'T' tại đây, sẽ khai báo nó làm thông số mẫu loại. Tuy nhiên, việc thực hiện thay đổi đó sẽ dẫn đến một lỗi vì từ định danh 'T' đã được sử dụng cho tên tham số mẫu trong mẫu lớp kèm theo. Chúng tôi phải thay đổi tên của thông số mẫu cho mẫu chức năng thành viên:

template <class T> 
class TMyPointTemplate 
{ 
public: 
    //... 
    template<class S> TMyPointTemplate<T> Interpolate 
       (const TMyPointTemplate<S> &OtherPoint) const 
    { 
    return ...; 
    }      
}; 
+0

Thực sự rất sâu sắc. Cảm ơn sự giúp đỡ của bạn! :-) –

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