2010-04-04 12 views
5

Esiste un modo per costruire un nuovo oggetto dall'oggetto specificato se i parametri del modello di entrambi gli oggetti sono identici in fase di esecuzione? Per esempio:Classi modello C++ e costruzione copia

Ho una classe template con la dichiarazione:

template<typename _Type1, typename _Type2> class Object; 

Avanti, ho due istanze del modello:

template class Object<char, int>; 
template class Object<wchar_t, wint_t>; 

Ora, voglio scrivere una funzione membro come come:

template<typename _Type1, typename _Type2> 
Object<char, int> Object<_Type1, _Type2>::toCharObject() { 
    if(__gnu_cxx::__are_same<_Type1, char>::__value) 
     return *this; 
    else { 
     //Perform some kind of conversion and return an Object<char, int> 
    } 
} 

ho provato un paio di tecniche, come l'utilizzo __gnu_cxx::__enable_if<__gnu_cxx::__are_same<_Type1, char>::__value, _Type1>::__type in un costruttore di copia per la classe Oject, ma io continuo a correre nell'errore:

error: conversion from ‘Object<wchar_t, wint_t>’ to non-scalar type ‘Object<char, int>’ requested 

Non c'è modo che io possa fare questo? Qualsiasi aiuto sarà molto apprezzato!

+2

I nomi dei tipi di modello non sono validi. Underscore seguito da identificatori maiuscoli sono ** riservati per l'implementazione **. Potrebbero scontrarsi con i nomi definiti dal compilatore o dalla libreria standard. – jalf

+0

@jaif: Non preoccuparti molto dei nomi di battesimo. Li ho scelti arbitrariamente per l'esempio. Tutto il mio codice è in realtà definito in un diverso spazio dei nomi, quindi non dovrebbero esserci conflitti. – themoondothshine

+3

Gli spazi dei nomi non sono i nomi dei problemi, come _Type1 sono riservati in TUTTE le circostanze (potrebbero essere macro, ad esempio), e in questo caso non è improbabile che vengano utilizzati dall'implementazione. O stai dicendo che ciò che hai postato non è il codice reale che causa il tuo problema? Beh, non farlo neanche io. –

risposta

4

Quello che dovrebbe funzionare, il problema è che il compilatore sta eseguendo un controllo di tipo sulla parte return *this, anche se i tipi non sono uguali (da cui l'errore di compilazione). Basta usare return (Object<char, int>)(*this); e si dovrebbe andare bene - l'unica volta che il codice verrà eseguito è quando i tipi sono uguali lo stesso, quindi il cast non fa altro che aggirare l'errore di compilazione.

In alternativa, è possibile utilizzare modello di specializzazione:

template <class _Type1, class _Type2> 
Object<char, int> toCharObject(Object<_Type1, _Type2> obj) 
{ 
    // Do conversion and return 
} 

// Specialisation when types are equal 
template <> 
Object<char, int> toCharObject(Object<char, int> obj) 
{ 
    return obj; 
} 

Questa è una funzione libera, come potete vedere. Puoi farlo come funzione membro, ma è più complicato perché non puoi specializzare la funzione dei singoli membri: devi specializzare l'intera classe. Puoi aggirare il problema definendo il codice non specializzato, ma è davvero brutto, e funziona altrettanto bene.

+0

@Peter: hai centrato l'unghia sulla testa !! Avrei dovuto pensare prima alla specializzazione dei modelli ... L'ho usato in un bel po 'di tempo. Duh !!! Grazie mille! – themoondothshine

+0

@Peter: ... ma in qualche modo non riesco a far funzionare il casting. Se provo a lanciarlo, il compilatore riporta "errore: cast non valido". – themoondothshine

+0

Ecco come funziona: 'return Object (* reinterpret_cast *> (this))' – themoondothshine