Cast Boost :: shared_array <char>для повышения :: shared_array <const char> - PullRequest
6 голосов
/ 04 декабря 2009

Как я могу разыграть boost::shared_array<char> до boost::shared_array<const char>?

Ответы [ 7 ]

6 голосов
/ 04 декабря 2009

Поскольку 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) );
3 голосов
/ 04 декабря 2009

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

Кроме того, вы уверены, что хотите 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);

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

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

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

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

1 голос
/ 22 июля 2011

Я бы не подумал об этом без удивительного ответа Кирилла, но вы можете эффективно продлить буст static_pointer_cast, который используется для shared_ptr с, чтобы работать на 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 );
1 голос
/ 04 декабря 2009

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

как это:

boost::shared_array<char> x(new int[13]);
const char *y = x.get();
1 голос
/ 04 декабря 2009

Я думаю, что вы не можете. Однако, если вам это действительно нужно, вы можете создать собственный класс Smart-указателя. Подсказки для этого можно найти здесь .

1 голос
/ 04 декабря 2009

Вы не можете.

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

0 голосов
/ 04 декабря 2009

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

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

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

...