2010-08-03 26 views
5

Tôi đang cố gắng viết một ngữ pháp có thể mở rộng bằng các hàm, nhưng dường như không tìm được cú pháp đúng để chấp nhận một hàm mẫu. Tôi đang sử dụng Visual C++ 2008. Nó sẽ chấp nhận một biến cùng loại với hàm mẫu, hoặc một hàm không có khuôn mẫu tương tự, nhưng không phải là chính hàm mẫu đó.Toán tử tải trọng << chấp nhận chức năng mẫu

Lỗi 1 lỗi C2679: nhị phân '< <': không có nhà điều hành tìm thấy trong đó có một toán hạng bên phải của loại 'quá tải chức năng' (hoặc không có chuyển đổi có thể chấp nhận) (dòng ***)

class Grammar { 
    friend Grammar operator << (const Grammar& lhs, const char* rhs) { 
     return lhs; // append rhs to grammar 
    } 
    template<typename T> 
    friend Grammar operator << (const Grammar& lhs, T (*rhs)()) { 
     return lhs; // append rhs() to grammar 
    } 
}; 

template<typename T> 
class ExpressionParticle { 
}; 

template<typename T> 
ExpressionParticle<T> Expression() ; 

ExpressionParticle<int> ExpressionInt(); 

int _tmain (int argc, _TCHAR *argv[]) 
{ 
    ExpressionParticle<int> (*p)(); 

    p = Expression<int>; 

    Grammar() << "p"; 
    Grammar() << p; 
    Grammar() << ExpressionInt; 
    Grammar() << Expression<int>; // *** 

Loại Expression<int> là gì nếu đây không phải là loại p ở trên? Loại của nó khác với loại ExpressionInt như thế nào.

+0

FWIW, đây biên dịch với g ++ 4.4.1 –

Trả lời

3

Mã của bạn có vẻ OK với tôi, và g ++ là tốt với điều đó quá. Điều này có vẻ là lỗi độ phân giải quá tải lạ trong Visual Studio. VS2005 dường như có cùng một vấn đề. Cách giải quyết có thể xảy ra là (được thử nghiệm với VS2005):

template<class T> 
T id(T t) {return t; } 
int main() 
{ 
    ExpressionParticle<int> (*p)(); 

    p = Expression<int>; 

    Grammar() << "p"; 
    Grammar() << p; 
    Grammar() << ExpressionInt; 
    Grammar() << id(Expression<int>); // *** 
} 
0

Thay đổi này:

class Grammar { 
    friend Grammar operator << (const Grammar& lhs, const char* rhs) { 
     return lhs; // append rhs to grammar 
    } 
    template<typename T> 
    friend Grammar operator << (const Grammar& lhs, T (*rhs)()) { 
     return lhs; // append rhs() to grammar 
    } 
}; 

này:

class Grammar { 
public: 
    Grammar& operator << (const char* rhs) { 
     return *this; // append rhs to grammar 
    } 
    template<typename T> 
    Grammar& operator << (const T &rhs) { 
     return *this; // append rhs() to grammar 
    } 
}; 
+0

'Grammar() << Biểu (); 'có một ý nghĩa hoàn toàn khác nhau. –

+0

ah! ... xấu của tôi .. tôi đã không nhận thấy một phần của nó. Nhưng cách anh ta quá tải toán tử << 'sai, IMO. Tôi sẽ thay đổi điều đó ngay bây giờ. –

+0

@Luther Tôi xin lỗi .. nhưng wat là ý nghĩa hoàn toàn khác của 'Biểu thức (); 'một lần nữa? Đó là một hàm mẫu và hàm nên được gọi là hàm. Phải không? Tôi đã làm việc nó trong Visual Studio 2008 và nó biên dịch nó! –

0

Như một công việc khác, tôi có thể làm cho nó hoạt động trên VS2010 bằng cách truyền. Tôi đã sử dụng typedef để thuận tiện. VS2008 có thể sẽ hoạt động tương tự.

int _tmain (int argc, _TCHAR *argv[]) 
{ 
    typedef ExpressionParticle<int> (*FCN)(); 

    ExpressionParticle<int> (*p)() = Expression<int>; 

    Grammar() << "p"; 
    Grammar() << p; 
    Grammar() << ExpressionInt; 
    Grammar() << static_cast<FCN>(Expression<int>); 
0

MSVC 2013 vẫn còn chứa các lỗi tương tự, nhưng ít nhất bây giờ bạn có thể sử dụng phiên bản mới hơn C++ 11 alias mẫu cú pháp nếu bạn đi với các giải pháp đúc:

template <typename T> 
using Fptr = ExpressionParticle<T>(*)(); 

Sau đó làm các diễn viên như thế này:

Grammar() << Fptr<int>(Expression<int>) << endl; 
Các vấn đề liên quan