2015-05-27 2 views
0

У меня есть контейнер, который я бы хотел заполнить указателями класса C. Однако я бы предпочел использовать Boost shared_ptr, чем тупые указатели.Размещение интеллектуальных указателей в контейнере STL

Я объявляю контейнер как container<C*>, но получаю эту ошибку:

no known conversion for argument 1 from ‘boost::shared_ptr<C>’ to ‘C* const&’ 

Как я должен объявить контейнер принять повышение общих PTRS? Если это возможно, я бы хотел, чтобы он тоже принимал немые указатели.


UPDATE: Из ответов, кажется, что контейнер действительно должен быть объявлен принимать смарт-указатели, это не может быть сделано, чтобы принять как умные или тупые указатели. То есть, нет принуждения от умных к немым или наоборот. Это верно?

+0

Возможно, вам понадобится контейнер Boost ptr. – chris

+0

'container >' ... это то, что вы ищете? Если нет, можете ли вы показать какой-то код того, что вы пытаетесь сделать. – Praetorian

+0

Создайте [MCVE] (http://stackoverflow.com/help/mcve), сообщения об ошибках без кода, вызывающего их, как известно, бесполезны. –

ответ

2

Простая рабочая демонстрация с использованием общих указателей C++ 11. Они аналогичны общим указателям Boost.

#include <iostream> 
#include <memory> 
#include <vector> 

int main(int argc, char* argv[]) 
{ 
    // Create vector 
    std::vector<std::shared_ptr<int>> buffer; 

    for(int i=0; i<10; i++) 
     buffer.push_back(std::make_shared<int>(i)); 

    for(int i=0; i<10; i++) 
     if((*buffer[i]) != i){ 
      std::cout << "Match invalid for " << i << "." << std::endl; 
      return 1; 
     } 
    std::cout << "Valid result" << std::endl; 

    return 0; 
} 

Я собирал это с помощью

g++ main.cpp -o main -std=c++11 
+0

Каким образом это демонстрирует вектор, содержащий как умные, так и немые указатели? – Yakk

+0

Вы можете запросить 'std :: shared_ptr' для внутреннего немого указателя, используя' std :: shared_ptr :: get'. В противном случае вы можете создать класс с помощью как shared_ptr, так и обычного указателя, чтобы вы также могли проверить. Однако это довольно уродливое решение. – msmith81886

+0

Да, но ОП запросил способ хранить немые указатели в контейнере. Сохранение немого указателя в интеллектуальном указателе выполнимо (даже если оно не делает его разумным в случае 'std :: shared_ptr '!), Но выше это не демонстрирует этого. – Yakk

0

Для того, чтобы использовать векторы, нужно явно указать тип объектов, которые они будут holding.In ваше дело будет boost::shared_ptr. Я также понимаю, что вы хотите хранить немые указатели в этом контейнере. Вероятно, вы имеете в виду необработанные указатели. Как уже упоминалось ранее, ваш контейнер может в основном хранить один тип, но есть исключения, например, типы связаны с помощью наследования или другого механизма (например, сериализации), для которого требуется определенное явное литье вниз, когда вы пытаетесь используйте эти объекты или тип является общим типом. Тем не менее. Вот еще один подход. Вам не нужен вектор, который хранит как умный указатель, так и необработанный указатель, так как вы всегда можете получить необработанный указатель из умного указателя. Ваш лучший подход заключается в создании вектора, как этот

std::vector<boost::shared_ptr<foo>> vec; 

выше создает вектор, который будет хранить общие указатели на Foo.

Тогда, когда-либо у вас есть общий указатель как таковой

boost::shared_ptr<foo> foo_ptr(new foo()); 

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

vec.push_back(foo_ptr) 

Когда вам нужно немого указатель вы могли бы сделать это

foo* f = vec[0].get(); 

Я прочитал ваше обновление, в котором вы указали

... it seems that the container must indeed be declared to take smart pointers, it can't be made to take either smart or dumb pointers.

Вы должны понимать, что boost::shared_ptr<Type> - это умный указатель.

+0

Нет: то, что запросит ОП. Я могу написать это более чем одним способом. Вопрос в том, каким образом OP хочет это сделать, а не «это невозможно». – Yakk

+0

Насколько я понимаю, OP хочет содержать оба типа в 'std :: vector'. Я не уверен, что 'std :: vector' может содержать несколько типов, если они не связаны. – Rajeshwar

+0

Множество способов: 'union',' std :: aligned_storage', 'void *' & 'type_id *' на более низком уровне, 'std :: experimental :: any',' boost :: variant', стирание пользовательского типа на более высоком уровне? Моя проблема в том, что вы сказали: «Вы не можете этого сделать». Возможно, они не должны этого делать. Возможно, вы не знаете, как это сделать. Но будьте осторожны на C++, когда говорите «это не может быть сделано»: зная, что не может быть сделано, иногда требуется знание всего, что можно сделать! – Yakk

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