2017-01-16 5 views
-2

Посмотрите на следующий фрагмент кода.Ошибка при переходе общего указателя в вектор

#typedef std::shared_ptr<node> node_ptr; 
std::vector<node_ptr> temp;    
for(int i=0; i<4; i++)    
{ 
    temp.push_back(&m_nodes.at(n[i]-1)) // Got error in this line 
} 

m_nodes определяется как вектор объектов-узлов.

std::vector<node> m_node; 

Когда я оценил этот код, я получил следующее сообщение об ошибке:

error: no matching function for call to 'std::vector<std::shared_ptr<node> >::push_back(__gnu_cxx::__alloc_traits<std::allocator<node> >::value_type*)' 
        temp.push_back(&m_nodes.at(n[i]-1)); 
                ^

Мои знания об указателях ограничен, и я не мог понять ошибку. Пожалуйста, помогите

EDIT
Из ответов, приведенных ниже, и через поиск Google, я в заключение, что вектор указателей является плохой идеей. Но в моем случае только необходимость заставила меня использовать вектор указателей. Я использую C++ для научных вычислений, а объект node содержит переменные, которые мне нужно вычислить. Поскольку количество узлов узла велико, его трудно копировать и перемещать каждый раз. Итак, для передачи функций и инициализации другого объекта класса мне нужно использовать указатель на узел или ссылку.
Если shared_ptr является неправильным выбором в моем контексте, есть ли другой простой эффективный способ сделать это? Поскольку я новичок в C++, я бы предпочел простое решение.

+0

унарный оператор '' & идет перед операндом – vu1p3n0x

+0

@ vu1p3n0x, Является ли это выше редактировать то, что вы сказали? – user294664

+0

Как вы научились C++? Почему вы (ab) используете макрос, в котором существует псевдоним типа? – StoryTeller

ответ

2

shared_ptr constructor, который принимает Y*, является explicit. Он не будет участвовать как пользовательское преобразование, чтобы превратить необработанный указатель в shared_ptr. И temp.push_back не перегружен, чтобы принять необработанный указатель. Отсюда и ваша ошибка.

Вы могли сделать ошибку во время компиляции уйти, но тогда ваша программа будет демонстрировать неопределенное поведение, когда shared_ptr s в temp будет начать называть delete на объектах, находящихся в собственности m_nodes.


И что использование макроса является ужасным. Используйте псевдоним типа:

using node_ptr = std::shared_ptr<node>; 

Поскольку вы, кажется, нужно не-владеющим указатели (shared_ptr для сложной семантики собственности). Прекрасно переносить вектор исходных указателей. В вашем случае, просто сделать псевдоним типа такой:

using node_ptr = node*; 

Это изменит семантику должным образом без перезаписи всего кода.

+0

Не могли бы вы дать мне предложение для редактирования? – user294664

+0

@ user294664 - См. Мое редактирование. – StoryTeller

0

Вы не можете push_back указатель на вектор смарт-указатели, вы должны использовать emplace_back() вместо того, чтобы построить общий указатель на месте:

// this will create a new shared_ptr in-place, and will call the appropriate constructor for it. 
temp.emplace_back(&m_nodes.at(n[i]-1)); 

Кроме того, вы должны использовать ЬурейеЕ вместо макроса:

typedef std::shared_ptr<node> node_ptr; 
// or, better yet: 
using node_ptr = std::shared_ptr<node> 
+0

Спасибо, это сработало. Но после успешной компиляции программы я получаю следующую ошибку после вывода - 'double free или corrupt (! Prev)'. Эта ошибка связана с вышеупомянутой проблемой? – user294664

+0

@ user294664, вы не можете создать вектор узлов, находящихся в стеке, а затем просто сделать интеллектуальные указатели своих адресов, потому что они будут удалены дважды. – SingerOfTheFall

+0

Не могли бы вы дать мне предложение? – user294664

Смежные вопросы