компилятор не будет компилировать интеллектуальный указатель с использованием -std = c ++ 11

Я пытаюсь скомпилировать простое объявление общего указателя, но использую g++ -std=c++11 main.cpp -o main с помощью cmd, но по некоторым причинам это вызывает кучу ошибок. Я пытался найти похожие вопросы в Stack Overflow, но ни один из них не соответствует моей проблеме.

код:

std::shared_ptr<int[]>array(new int[100]);

Заголовочные файлы:

#include<iostream>
#include<memory>

версия компилятора: g ++ (MinGW.org GCC-6.3.0-1) 6.3.0

Ошибка:

In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\shared_ptr.h:52:0,
                 from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\memory:82,
                 from main.cpp:2:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\shared_ptr_base.h: In instantiation of 'std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1*) [with _Tp1 = int; _Tp = int []; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\shared_ptr.h:117:32:   required from 'std::shared_ptr<_Tp>::shared_ptr(_Tp1*) [with _Tp1 = int; _Tp = int []]'
main.cpp:7:42:   required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\shared_ptr_base.h:885:39: error: cannot convert 'int*' to 'int (*)[]' in initialization
         : _M_ptr(__p), _M_refcount(__p)
                                       ^`

Я относительно новичок и не знаю, что означает эта ошибка. Любые предложения будут полезны.


person Muhammad Ali Khan    schedule 13.10.2018    source источник
comment
Рассмотрим замену от shared_ptr на std::array.   -  person user4581301    schedule 13.10.2018


Ответы (2)


До C++17 std::shared_ptr не мог обрабатывать динамически выделяемые массивы. Обновите свой компилятор для поддержки C++17, и ваш код будет успешно компилироваться.

РЕДАКТИРОВАТЬ: существует обходной путь для более ранних версий. Вы могли использовать:

std::shared_ptr<int> sp(new int[10], custom_deleter<int>{});

где custom_deleter будет функцией, которая будет использоваться для освобождения выделенной памяти. В этом случае будет достаточно простого delete[] (вместо неявного delete внутри деструктора shared_ptrs):

template< typename T >
struct custom_deleter
{
    void operator ()(const T* arr)
    { 
        delete[] arr; 
    }
};

но поскольку вы уже используете C++11, можно заменить структуру лямбда-выражением, что упростит код:

std::shared_ptr<int> sp(new int[10], [](const int* arr){ delete[] arr; });
person Fureeish    schedule 13.10.2018
comment
Можете ли вы предложить какие-либо ссылки, по которым я мог бы скачать компилятор c ++ 17? - person Muhammad Ali Khan; 13.10.2018
comment
Компилятора C ++ 17 не существует - только реализации, которые в большей или меньшей степени поддерживают стандарт, например nuwen.net/mingw.html - person ; 13.10.2018
comment
@MuhammadAliKhan Похоже, для поддержки библиотеки shared_ptr<T[]> требуется как минимум gcc 7.1 - person Blastfurnace; 14.10.2018

Ошибка «невозможно преобразовать ...» является ошибкой типа, это означает, что вы использовали неправильный тип данных. В этом случае он специально сообщает вам, что конструктору для std::shared_ptr<int[]> требуется тип аргумента int (*)[], но вы предоставляете аргумент типа int *. Поскольку компилятор не знает, как преобразовать int * в int (*)[], вы получаете эту ошибку.

В любом случае не следует использовать shared_ptr для управления массивами в стиле C. Я бы посоветовал перейти на контейнеры STL, std::array<int, N> или std::vector<int> в зависимости от того, знаете ли вы размер во время компиляции или нет. Затем любой тип контейнера STL можно поместить в интеллектуальный указатель, если хотите.

person JMAA    schedule 13.10.2018