2009-12-04 2 views

ответ

6

Поскольку shared_array не имеет add_ref метод, который вы могли бы подражать его следующим образом:

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

Очень умный. Ницца :) – Catskul

1

Вы не можете.

Поскольку оба типа основаны на шаблоне, оба типа совершенно различны для компилятора.

0

Такое формирование с использованием компилятора не может быть возможным.

Внутренние элементы класса с параметром шаблона с параметром const могут сильно отличаться от класса без одного из-за функции специализированного шаблона.

Кроме того, использование такой функции иногда является фоном для проверок времени компиляции, которые просто не позволяют создать экземпляр типа A<const T> для каждого случая, когда тип A<T> верен.

+1

Невозможно? Тем не менее boost :: shared_ptr поддерживает неявное преобразование из производных в базовые типы (и не const const) и всевозможные приведения. –

+0

Это действительно поддерживает * преобразование *. Но это не может быть * type-casted *. –

+0

Он поддерживает броски, если вы не имеете в виду ничего другого. Например, 'boost :: shared_ptr ptr (boost :: static_pointer_cast (base_shared_ptr));' –

1

Я думаю, вы не можете. Если вам это действительно нужно, вы можете создать собственный класс интеллектуальных указателей. Подсказки для этого можно найти here.

3

Другие ответы верны, вы не можете и не должны.

Кроме того, вы уверены, что хотите boost::shared_array<const char>, а не const boost::shared_array<char>?

Практически, это работает:

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

НО это не очень хорошая идея, и работает только тогда, когда повышение :: shared_array и повышение :: shared_array имеют ту же реализацию. Шаблоны могут быть частично специализированы:

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

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

Выполнение переинтерпретировать ввергнуть между TwoImplementations<int> и TwoImplementations<const int> просто неправильно.

+1

Никогда не используйте такой reinterpret_cast, особенно в этом случае! Вообще говоря, reinterpret_cast на 99% не переносится. – rmn

+0

Я знаю это и признаю это в своем посте. Поэтому, пожалуйста, не делайте снизу. Это языковая функция, она может работать и в 1% случаев может быть даже полезной. – Sebastian

+0

@rmn: Один размер не подходит всем, я согласен, что в этом месте это плохая идея, но никогда не говори никогда. –

1

Вы можете использовать метод get() для получения базового символа char *, который автоматически конвертируется в const char *, но не назначает его другому shared_array, потому что тогда вы дважды удалите данные. Просто используйте его так, как вам нужно.

так:

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

Я бы не подумал об этом, не удивительный ответ Кирилла, но вы можете эффективно продлить static_pointer_cast форсирования, который используется для shared_ptr s для работы на shared_array с таким образом:

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

с этим вы можете сделать что-то вроде:

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

uintArrayPtr = static_pointer_cast<unsigned int>(intArrayPtr); 
Смежные вопросы