2016-05-02 20 views
8

Sto tentando di compilare una funzione amico in una classe basata su modelli, ma il messaggio di errore e l'avviso non sono comprensibili. Ho fatto una dimostrazione del problema. L'errore che sto ricevendo è:Funzione membro membro classe operatore moderata

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

non ti servono la prima dichiarazione di 'operatore +', che è sbagliato. – Holt

+0

Questo è un esempio del problema. Ho bisogno di tre forme nel mio codice attuale: C operatore + (const C e altro), operatore C + (const B e altro) e operatore C (const B & lhs, const C & rhs). N.B. codice di compilazione non reale, solo le forme generali del bisogno. – JadziaMD

risposta

3

Questa dichiarazione:

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

... è sbagliato a causa della <A,B> tra il operator+ e (, io non so davvero che cosa voleva fare qui. Si dovrebbe utilizzare questo modulo se si fosse a specializzare un modello operator+, ma non si è qui, si è sovraccarico uno.

Questa dichiarazione dovrebbe essere:

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

Poi si dovrebbe esplicitamente specificare nella friend dichiarazione che si desidera una versione specializzata per scrittura:

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

Hai bisogno di mettere questa prima operator+, otherwize il compilatore penserà che questa è una specializzazione di una funzione non basata su modelli.

In ogni caso, se non si ha una vera ragione per mettere il proprio codice al di fuori della classe C, vorrei andare alla soluzione @ Jarod42.


intera Il codice dovrebbe essere simile a questa:

// 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

Ho una tale ragione. :) Ho inserito le modifiche al codice suggerite nell'esempio, ma ora ho ricevuto l'errore: prog.cpp: 19: 24: errore: dichiarazione di 'operator +' come non funzionante amico C operator + <> (const B & lhs, const C & rhs); ^ prog.cpp: 19: 24: errore: previsto ";" alla fine della dichiarazione membro prog.cpp: 19: 26: errore: atteso id non qualificato prima di '<' token amico C operatore + <> (const B & lhs, const C & rhs) – JadziaMD

+1

@JadziaMD È necessario inserire l'operatore 'C + <> (const B & lhs, const C & rhs) '** before ** qualsiasi altro operatore' non-templated + 'dentro' C'. Aggiornerò la mia risposta – Holt

5

Il più semplice è quello di inline di codice all'interno della classe:

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

Il codice non inline nel classe, che richiede molta attenzione come ordine di dichiarazione di dichiarazione, strano sintassi <>:

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

Problemi correlati