C Инициализация атрибута массива unique_ptr в классе

#c

#c

Вопрос:

Я хочу использовать unique_ptr для своего класса здесь (вместо vector по моим собственным причинам). Но я не уверен, как инициализировать new [] массив с его помощью. Вот как выглядит мой код

 template <typename T>
class kmap
{
private:
  const std::vector<std::string> amp;data;
  std::unique_ptr<T> table;
public:
  kmap(std::vector<std::string> amp;kmers);
};

template <typename T>
kmap<T>::kmap(std::vector<std::string> amp;kmers) : data(kmers)
{
  this->table = std::unique_ptr<T[]>(new T[kmers.size()*2]);
}

 

Теперь я могу инициализировать это с std::unique_ptr<T>(new T[kmers.size()*2] ); помощью, но я скептически отношусь к тому, что он может удалить только самый первый элемент массива вместо освобождения всего блока, когда объект выходит из области видимости. Мой скептицизм напрасен или возможно инициализировать это как массив?

Вот часть сообщения об ошибке, которое я получаю при инициализации этого с помощью T = int :

 /home/sflash/Documents/misc/kmap.cpp: In instantiation of ‘kmap<T>::kmap(std::vector<std::__cxx11::basic_string<char> >amp;) [with T = int]’:
/home/sflash/Documents/misc/kmap.cpp:75:23:   required from here
/home/sflash/Documents/misc/kmap.cpp:27:15: error: no match foroperator=’ (operand types are ‘std::unique_ptr<int, std::default_delete<int> >’ and ‘std::unique_ptr<int [], std::default_delete<int []> >’)
   27 |   this->table = std::unique_ptr<T[]>(new T[kmers.size()*2]);
      |   ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c  /10.2.0/memory:83,
                 from /home/sflash/Documents/misc/kmap.cpp:2:
/usr/include/c  /10.2.0/bits/unique_ptr.h:371:19: note: candidate: ‘std::unique_ptr<_Tp, _Dp>amp; std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Tp, _Dp>amp;amp;) [with _Tp = int; _Dp = std::default_delete<int>]’
  371 |       unique_ptramp; operator=(unique_ptramp;amp;) = default;
      |                   ^~~~~~~~
/usr/include/c  /10.2.0/bits/unique_ptr.h:371:29: note:   no known conversion for argument 1 from ‘std::unique_ptr<int [], std::default_delete<int []> >’ to ‘std::unique_ptr<int, std::default_delete<int> >amp;amp;’
  371 |       unique_ptramp; operator=(unique_ptramp;amp;) = default;
      |                             ^~~~~~~~~~~~
/usr/include/c  /10.2.0/bits/unique_ptr.h:386:2: note: candidate: ‘template<class _Up, class _Ep> typename std::enable_if<std::__and_<std::__and_<std::is_convertible<typename std::unique_ptr<_Up, _Ep>::pointer, typename std::__uniq_ptr_impl<_Tp, _Dp>::pointer>, std::__not_<std::is_array<_Up> > >, std::is_assignable<_T2amp;, _U2amp;amp;> >::value, std::unique_ptr<_Tp, _Dp>amp;>::type std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Up, _Ep>amp;amp;) [with _Up = _Up; _Ep = _Ep; _Tp = int; _Dp = std::default_delete<int>]’
  386 |  operator=(unique_ptr<_Up, _Ep>amp;amp; __u) noexcept

 

Как я скомпилировал: g -pipe -O2 -std=c 14 "$file" -o exe -lm

Комментарии:

1. Это std::unique_ptr<T> table; не тот тип, std::unique_ptr<T[]>(new ...) который вы пропустили [] в элементе таблицы.

Ответ №1:

unique_ptr имеет специализацию при объявлении с типом массива:

 std::unique_ptr<T[]> table;
 

В этой ситуации delete[] будет использоваться для удаления указателя.

В качестве бонуса эта специализация также определяет overloaded operator[] , чтобы упростить его использование в качестве массива.