2009-12-04 5 views

Répondre

6

Depuis shared_array n'a pas de méthode add_ref, vous pouvez l'imiter comme suit:

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

Très intelligent. Agréable :) – Catskul

1

Vous ne pouvez pas. Comme les deux types sont basés sur un modèle, les deux types sont complètement différents pour le compilateur.

0

Un tel moulage généré par un compilateur ne peut pas être possible.

Les composants internes de la classe avec le paramètre de modèle const-qualified peuvent différer considérablement de la classe sans un, en raison de la fonction de spécialisation de modèle.

En outre, l'utilisation de cette fonctionnalité est parfois un arrière-plan pour les vérifications de compilation qui ne permettent simplement pas l'instanciation du type A<const T> pour tous les cas où le type A<T> est correct.

+1

Pas possible? Pourtant, boost :: shared_ptr supporte la conversion implicite des types dérivés en base (et non-const en const) et toutes sortes de conversions. –

+0

Il supporte en effet * conversion *. Mais il ne peut pas être * casté *. –

+0

Il supporte les lancers, à moins que vous ne vouliez dire autre chose entièrement. Par exemple, 'boost :: shared_ptr ptr (boost :: static_pointer_cast (base_shared_ptr));' –

1

Je pense que vous ne pouvez pas. Au cas où vous en auriez vraiment besoin, vous pouvez créer une classe personnalisée smart-pointer. Des conseils pour cela peuvent être trouvés here.

3

Les autres réponses sont correctes, vous ne pouvez pas et vous ne devriez pas.

En outre, êtes-vous sûr de vouloir un boost::shared_array<const char> et non un const boost::shared_array<char>?

Pratiquement, cela fonctionne:

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

mais il est pas une bonne idée et ne fonctionne que si boost :: shared_array et boost :: shared_array ont la même mise en œuvre. Les modèles peuvent être partiellement spécialisés:

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

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

Faire un jeté entre TwoImplementations<int> réinterpréter et TwoImplementations<const int> est tout simplement faux.

+1

N'utilisez jamais un tel reinterpret_cast, surtout dans ce cas! De manière générale, reinterpret_cast est 99% non portable. – rmn

+0

Je le sais et le reconnais dans mon post. Alors s'il vous plaît ne pas downvote. C'est une caractéristique du langage, ça peut marcher et dans 1% des cas, ça peut même être utile. – Sebastian

+0

@rmn: Une taille ne convient pas à tous, je suis d'accord que dans ce lieu c'est une mauvaise idée, mais ne jamais dire jamais. –

1

Vous pouvez utiliser la méthode get() pour obtenir le caractère char * sous-jacent, qui est automatiquement convertible en un const char *, mais ne l'attribuez pas à un autre shared_array, car les données seront supprimées deux fois. Utilisez-le simplement comme vous en avez besoin.

comme ceci:

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

Je ne l'aurais pas pensé à cela sans réponse impressionnante de Kirill, mais vous pouvez étendre effectivement boost static_pointer_cast qui est utilisé pour shared_ptr s de travailler sur shared_array s comme tel:

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)); 
} 

avec que vous pouvez faire quelque chose comme:

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

uintArrayPtr = static_pointer_cast<unsigned int>(intArrayPtr); 
Questions connexes