2013-03-18 4 views
5

Ho il seguente metodo all'interno di un file di intestazione chiamato 'filter.h':C++ non può chiamare il metodo (con template) da dentro il metodo basato su modelli

namespace std{ 

//some code 

template <class T, class S, class BorderMethod> 
tImage<T> binomial(const tImage<T> &in, const size_t k = 3) { 
    //do some computations 

    tImage<T> img = in.convolve<T, BorderMethod>(in, kernel); 
    return img; 
} 
} 

prima cosa che ho notato: la definizione di questo metodo ha luogo all'interno del file di intestazione. È quella procedura standard?

Ora, il problema reale: la chiamata al metodo convolve non funziona, anche se in possiede tale metodo. Ecco la definizione del metodo convolve all'interno della classe tImage<T>:

tImage<T> convolve(const gravis::tImage<T>& image, const gravis::tArray<typename tImageTraits<T>::Float_t>& kernel); 

Come devo chiamare questa funzione?

+0

'in' è l'argomento' const', quindi una funzione membro non-'const' non può essere invocata su di essa. – hmjd

+0

'binomiale' sembra pensare che' convolve' sia un modello di funzione, ma 'convolve' non assomiglia a un modello di funzione (solo una funzione membro di una classe template). – aschepler

+0

Perché il tuo codice è in 'namespace std'? È illegale aggiungere al namespace 'std' (oltre alle specializzazioni). – Praetorian

risposta

6

Per prima cosa ho notato: la definizione di questo metodo avviene all'interno del file di intestazione. È quella procedura standard?

Sì. Normalmente le definizioni dei modelli di funzione sono inserite nelle intestazioni. Se sono stati relegati in un file separato .cpp, il compilatore non sarebbe in grado di istanziarli implicitamente quando viene richiamato e, a meno che non si agisca correttamente, il linker si lamenterà di riferimenti non definiti. Vedere this Q&A on StackOverflow per ulteriori informazioni.

La chiamata al metodo convolve non funzionerà, anche se in possesso di tale metodo.

convolve() è una funzione non const membro, e si sta tentando di richiamare attraverso un riferimento a const. Questo è illegale e il compilatore te lo dice.


Inoltre, come giustamente rilevato dalla JBentley nella sua risposta, non è possibile aggiungere nuove dichiarazioni o definizioni per la std namespace. Per Il paragrafo 17.6.4.2.1/1 della C++ 11 standard:

Il comportamento di un programma C++ è indefinito se si aggiunge dichiarazioni o definizioni di namespace std o ad uno spazio dei nomi all'interno di namespace std, salvo diversa specificato. [...]

+0

Grazie! Ho chiamato lo spazio dei nomi 'std' a causa della mancanza di un altro nome per questa specifica domanda ... ma ancora, non ero a conoscenza del fatto, che non posso nominare il mio spazio dei nomi' std', quindi grazie comunque per questo . – kaufmanu

2

Anche se non è la causa del problema, il codice è undefined comportamento perché si è illegalmente posizionato all'interno del std spazio dei nomi.

Vedere this question o this one.

+0

+1, non l'avevo notato. Ne parlerò anche nella mia risposta –