2009-12-04 19 views

Respuesta

6

Desde shared_array no tiene add_ref método que podría emular la siguiente manera:

struct MagicDeleter { 
    MagicDeleter(boost::shared_array<char> ptr) : ptr(ptr) {}; 
    template<typename T> void operator()(T*) {} 
protected: 
    boost::shared_array<char> ptr; 
}; 

... 

boost::shared_array<char> orig_ptr(some_val); 
boost::shared_array<const char> new_ptr(orig_ptr.get(), MagicDeleter(orig_ptr)); 
+0

Muy inteligente. Agradable :) – Catskul

1

No puede.

Como ambos tipos se basan en una plantilla, ambos tipos son completamente diferentes para el compilador.

0

Tal conversión generada por el compilador no puede ser posible.

Las partes internas de la clase con el parámetro de la plantilla const const pueden diferir dramáticamente de la clase sin una, debido a la función de especialización de la plantilla.

Por otra parte, el uso de dicha característica es a veces un fondo para verificaciones en tiempo de compilación que simplemente no permiten la instanciación de tipo A<const T> para cada caso en que el tipo A<T> es correcto.

+1

¿No es posible? Sin embargo, boost :: shared_ptr admite la conversión implícita de tipos derivados a básicos (y no const a const) y todo tipo de conversiones. –

+0

De hecho, admite * conversión *. Pero no puede ser * moldeado *. –

+0

No admite moldes, a menos que signifique algo completamente diferente. Por ejemplo, 'boost :: shared_ptr ptr (boost :: static_pointer_cast (base_shared_ptr));' –

1

Creo que no se puede. En caso de que realmente lo necesite, puede crear una clase personalizada de puntero inteligente. Sugerencias para eso se puede encontrar here.

3

Las otras respuestas son correctas, no puede y no debe.

Además, ¿está seguro de que quiere un boost::shared_array<const char> y no un const boost::shared_array<char>?

la práctica, esto funciona:

boost::shared_array<char> acz; 
boost::shared_array<const char>& acz2 = reinterpret_cast< boost::shared_array<const char>& >(acz); 

pero no es una buena idea y sólo funciona si impulso :: shared_array e impulsar :: shared_array tienen la misma aplicación. Las plantillas pueden ser parcialmente especializados:

template<class T> 
struct TwoImplementations { 
    int m_nIntMember; 
}; 

template<> 
struct TwoImplementations< const T > { 
    double m_fDoubleMember; 
}; 

Haciendo un reinterpretar fundido entre TwoImplementations<int> y TwoImplementations<const int> es simplemente incorrecto.

+1

¡Nunca use este reinterpret_cast, especialmente en este caso! En términos generales, reinterpret_cast es 99% no portátil. – rmn

+0

Lo sé y lo reconozco en mi publicación. Entonces, por favor, no disminuya la votación. Es una función de idioma, puede funcionar y en el 1% de los casos incluso puede ser útil. – Sebastian

+0

@rmn: Un tamaño no sirve para todos, estoy de acuerdo en que en este lugar es una mala idea, pero nunca digas nunca. –

1

Puede usar el método get() para obtener el char * subyacente, que es auto convertible en un const char * - pero no lo asigne a otro shared_array porque entonces tendrá los datos eliminados dos veces. Solo úsalo como lo necesites.

así:

boost::shared_array<char> x(new int[13]); 
const char *y = x.get(); 
1

yo no habría pensado en esto sin respuesta impresionante de Kirill, pero se puede extienda con eficacia el static_pointer_cast del alza que se utiliza para shared_ptr s para trabajar en shared_array s como eso:

template<typename OriginalType> 
struct SharedPtrCastHelper 
{ 
    public: 
    SharedPtrCastHelper(const OriginalType & ptr) : ptr(ptr) {}; 
    template<typename T> void operator()(T*) {} 

    protected: 
    OriginalType ptr; 
}; 


template<typename OutT, typename InT> 
boost::shared_array<OutT> 
static_pointer_cast(const boost::shared_array<InT> & inSharedPtr) 
{ 
    typedef SharedPtrCastHelper<boost::shared_array<InT> > Helper; 

    return boost::shared_array<OutT>((OutT*)inSharedPtr.get(), 
            Helper(inSharedPtr)); 
} 

con que se puede luego hacer algo como:

boost::shared_array<int>   intArrayPtr(new int[40]); 
boost::shared_array<unsigned int> uintArrayPtr; 

uintArrayPtr = static_pointer_cast<unsigned int>(intArrayPtr); 
Cuestiones relacionadas