2016-05-02 37 views
8

Tôi đang cố gắng để có được một chức năng bạn bè bên trong một lớp templated để biên dịch, nhưng thông báo lỗi và cảnh báo tôi không hiểu. Tôi đã thực hiện một cuộc biểu tình của vấn đề. Các lỗi tôi nhận được là:Chức năng của thành viên Operated Class Friend Operating

prog.cpp:8:57: error: non-class, non-variable partial specialization C operator+(const B& lhs, const C& rhs);

prog.cpp:15:59: warning: friend declaration 'C operator+(const B&, const C&)' declares a non-template function [-Wnon-template-friend] friend C operator+(const B& lhs, const C& rhs);

prog.cpp:15:59: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)

#include <iostream> 
using namespace std; 

template<typename A, typename B> 
class C; 

template<typename A, typename B> 
C<A, B> operator+<A, B>(const B& lhs, const C<A, B>& rhs); 

template<typename A, typename B> 
struct C 
{ 
    A val_; 
    C operator+(const C& other) const; 
    friend C<A, B> operator+(const B& lhs, const C<A, B>& rhs); 
}; 

template<typename A, typename B> 
C<A, B> C<A, B>::operator+(const C<A, B>& other) const 
{ 
    C<A, B> c; 
    c.val_ = this->val_ + other.val_; 
    return c; 
} 

template<typename A, typename B> 
C<A, B> operator+(const B& lhs, const C<A, B>& rhs) 
{ 
    C<A, B> c; 
    c.val_ = lhs + rhs.val_; 
    return c; 
} 

int main() 
{ 
    C<string, char> c0,c1; 
    c0.val_ = " C0 "; 
    c1.val_ = " C1 "; 
    cout << "Stuct:" << (c0 + c1).val_ << '\n'; 
    cout << "Friend:" << ('~' + c1).val_ << endl; 
    return 0; 
} 
+0

Bạn không cần phải khai báo đầu tiên của 'operator +', đó là sai. – Holt

+0

Đây là một ví dụ về vấn đề. Tôi cần ba biểu mẫu trong mã thực tế của tôi: toán tử C + (const C & other), toán tử C + (const B & other), và toán tử C (const B & lhs, const C & rhs). N.B. không thực sự biên dịch mã, chỉ là các dạng chung của nhu cầu. – JadziaMD

Trả lời

3

khai này:

template<typename A, typename B> 
C<A, B> operator+<A, B>(const B& lhs, const C<A, B>& rhs); 

... là sai vì <A,B> giữa operator+(, tôi không thực sự biết những gì bạn muốn làm ở đây. Bạn sẽ sử dụng biểu mẫu này nếu bạn đã đến chuyên một templated operator+, nhưng bạn không ở đây, bạn đang quá tải một.

khai này nên là:

template<typename A, typename B> 
C<A, B> operator+ (const B& lhs, const C<A, B>& rhs); 

Sau đó, bạn explicitely nên xác định trong friend khai của bạn mà bạn muốn có một phiên bản đặc biệt của thành văn bản:

friend C<A,B> operator+<>(const B& lhs, const C<A,B>& rhs); 

Bạn cần phải đặt này trước khi operator+ của bạn, otherwize trình biên dịch sẽ nghĩ rằng đây là một chuyên môn của một chức năng không templated.

Dù sao, nếu bạn không có lý do thực sự để đặt mã của bạn bên ngoài lớp C, tôi sẽ đi @ Jarod42 giải pháp.


toàn bộ mã của bạn sẽ trông như thế này:

// Declaration of struct C with delayed definition 
template <typename A, typename B> 
struct C; 

// Initial declaration of templated operator+ 
template <typename A, typename B> 
C<A, B> operator+ (const B&, const C<A, B>&); 

// Definition of C 
template <typename A, typename B> 
struct C { 

    friend C operator+<> (const B&, const C&); 

    // This must be AFTER the templated operator+ 
    C operator+ (const C&) const; 
}; 

template<typename A, typename B> 
C<A, B> C<A, B>::operator+(const C<A, B>& other) const { 

} 

template<typename A, typename B> 
C<A, B> operator+(const B& lhs, const C<A, B>& rhs) { 

} 
+0

Tôi có lý do như vậy. :) Tôi đã đưa vào các thay đổi mã đề nghị trong ví dụ, nhưng bây giờ tôi nhận được lỗi: prog.cpp: 19: 24: lỗi: khai báo của 'operator +' là phi chức năng người bạn C operator + <> (const B & lhs, const C & rhs); ^ prog.cpp: 19: 24: error: expected ';' ở cuối khai báo thành viên prog.cpp: 19: 26: lỗi: dự kiến ​​không đủ tiêu chuẩn-id trước '<' token người bạn C toán tử + <> (const B & lhs, const C & rhs) – JadziaMD

+1

@JadziaMD Bạn cần đặt toán tử 'C + <> (const B & lhs, const C & rhs) '** trước ** bất kỳ toán tử' phi templated nào khác 'bên trong' C'. Tôi sẽ cập nhật câu trả lời của mình. – Holt

5

Cách đơn giản nhất là để nội tuyến mã bên trong lớp:

template <typename A, typename B> 
struct C 
{ 
    A val_; 
    C operator+(const C& other) const 
    { 
     C c; 
     c.val_ = this->val_ + other.val_; 
     return c; 
    } 

    friend C operator+ (const B& lhs, const C& rhs) 
    { 
     C c; 
     c.val_ = lhs + rhs.val_; 
     return c; 
    } 
}; 

Demo

Mã này không inlined trong lớp, đòi hỏi nhiều sự chú ý như tờ khai tuyên bố trước, lạ cú pháp <>:

template <typename A, typename B> struct C; 

template <typename A, typename B> 
C<A, B> operator+ (const B& lhs, const C<A, B>& rhs); 

template <typename A, typename B> 
struct C 
{ 
    A val_; 

    friend C<A, B> operator+<> (const B& lhs, const C<A, B>& rhs); 

    C operator+(const C& other) const; 
}; 


template <typename A, typename B> 
C<A, B> operator+ (const B& lhs, const C<A, B>& rhs) 
{ 
    C<A, B> c; 
    c.val_ = lhs + rhs.val_; 
    return c; 
} 

template <typename A, typename B> 
C<A, B> C::operator+(const C<A, B>& other) const 
{ 
    C<A, B> c; 
    c.val_ = this->val_ + other.val_; 
    return c; 
} 

Demo

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