2015-02-05 9 views
9

Ho un problema simile a this one.Soppressione "Classe base 'classe X' deve essere inizializzata esplicitamente nel costruttore di copie" dall'intestazione della libreria per la classe modello

Sto utilizzando una libreria di terze parti. Esso definisce le classi come qui (finto tutti i nomi a causa di problemi di licenza), nel file di headers/things.h:

class A { 
public: 
    virtual ~A() {} 
}; 


template < class T, class U > 
class B : virtual public A { 
public: 
    B(T) {} 

    B(const B< T,U >) {} 

    virtual ~B() {} 
}; 


template < class T, class U > 
class C : virtual public B< T, U > { 
public: 
    C(T t) : B < T, U > (t) {} 

    C(const C< T,U > &other) : B< T,U >(other) {} 

    ~C() {} 
}; 

Additionaly, ancora nell'intestazione libreria:

typedef C< int, int > CC; 

Il messaggio di errore è:

cc1plus: warnings being treated as errors 
../headers/things.h: In copy constructor ‘C<T, U>::C(const C<T, U>&) [with T = int, U = int]’: 
things.cpp:5: instantiated from here 
../headers/things.h:22: warning: base class ‘class A’ should be explicitly initialized in the copy constructor 
../headers/things.h: In copy constructor ‘B<T, U>::B(const B<T, U>&) [with T = int, U = int]’: 
../headers/things.h:23: instantiated from ‘C<T, U>::C(const C<T, U>&) [with T = int, U = int]’ 
things.cpp:5: instantiated from here 
../headers/things.h:12: warning: base class ‘class A’ should be explicitly initialized in the copy constructor 

In things.cpp, ho:

#include "things.h" 

CC make_cc() { 
    CC cc(123); 
    return cc; 
} 

int main() { 
    CC cc = make_cc(); 
    return 0; 
} 

layout di file è:

../ 
|-- source 
| `-- things.cpp 
`-- headers 
    `-- things.h 

Sono a conoscenza di ciò che questo significa avvertimento e io non sto chiedendo per questo. Dato che si trova in una libreria di terze parti, sono molto riluttante a modificarlo (correggerlo) per motivi di manutenzione. Voglio semplicemente ignorare questo avvertimento.

sto la compilazione il mio codice con:

g++ things.cpp -o things -Wall -Wextra -Werror -isystem ../headers/ 

Sto usando -isystem per specificare la directory, in quanto la documentazione gcc affermano che:

Tutte le avvertenze, diversi da quelli generati da '# warning '(consultare Diagnostica), vengono soppressi mentre GCC sta elaborando un'intestazione di sistema. (...) L'opzione della riga di comando -isystem aggiunge il proprio argomento all'elenco di directory in cui cercare le intestazioni, proprio come -I. Eventuali intestazioni trovate in quella directory saranno considerate intestazioni di sistema.

Questo sembra funzionare in generale, poiché quasi tutti gli avvisi della libreria di terze parti sono effettivamente soppressi.

Purtroppo, come questa dichiarazione sembra essere un'istanza di una typedef 'd classe su modelli, il compilatore pensa che sia il mio codice che si sta compilando, non il (falso) un colpo di testa del sistema.

Come detto nella domanda di riferimento, è impossibile sopprimere solo questo avviso, e dovrei disabilitare -Wextra invece, che non voglio fare.

Domanda: È possibile sopprimere questo avviso in ogni caso? Per far sapere a gcc che non è il mio codice, ma il codice della libreria?

Sto utilizzando gcc 4.1.2.

+0

gcc-4.1.2 ha 8 anni ora, è la versione che devi usare? Ho provato il tuo codice di esempio con gcc-4.6, gcc-4.8, gcc-4.9 e clang ++ - 3.4 e nessuno di loro aveva questo avvertimento. – SirGuy

+0

Il codice che hai postato produce molti errori ma non l'avviso che hai citato. Per favore costruisci un MCVE che mostri il problema. – Wintermute

+0

Sfortunatamente sì - il fornitore della libreria (e framework in generale) afferma che questa è l'unica versione ufficialmente supportata di gcc per Linux. Lo stesso vale per il dialetto, usiamo 'gnu ++ 98'. – rubikonx9

risposta

1

Come altri hanno detto, usando un compilatore più recente sembra essere un approccio migliore rispetto quanto segue, ma come si sta sembra essere legato le mani, si consideri il seguente approccio:

creare classi wrapper per la terza parte classi di librerie lungo le linee di

class MyCC { 
    CC cc; 
}; 

template<typename T, typename U> 
class MyB { 
    B<T, U> b; 
}; 

Inoltrare qualsiasi chiamata di funzione rilevante per rendere i wrapper trasparenti come si ritiene necessario. In alternativa è possibile utilizzare qualcosa come BOOST_STRONG_TYPEDEF.

L'intestazione (s) in cui sono definiti questi wrapper potrebbe quindi avere in cima al file:

#pragma GCC system_header 

Speriamo che pragma sopprimerà l'avviso nella unica client che utilizza direttamente la libreria , mentre tutti gli altri codici potrebbero invece utilizzare i wrapper, quindi non hanno bisogno del pragma.

+0

Sto cercando di implementare la soluzione che hai proposto. Si prega di dare un'occhiata qui: http://pastebin.com/sGWLbPZ4, è questo che intendevi? Io, il #pragma non sembra aiutare, sto ancora ricevendo avvisi: '../headers/things.hpp: nel costruttore di copia 'C :: C (const C &) [con T = int , U = int] ': ../headers/x.hpp:28: istanziato da qui' – rubikonx9

+0

Intendevo posizionare il pragma prima delle cose incluse.hpp. Puoi verificare se questo risolve il problema? –

+0

@Matthiias Vegh, l'ho controllato e non ha alcun effetto. – rubikonx9

Problemi correlati