как хранить указатели на карте - PullRequest
15 голосов
/ 03 ноября 2010

Я работаю над одним из проектов, который требует

class MyObj;

map<string, MyObj*> myMap;

Здесь логика для сопоставления имени файла с классом MyObj.

Если я попытаюсь вставить следующее

string strFilename = "MyFile";
MyObj* pObj  = new MyObj();

myMap.insert(strFileName, pObj); // This line throwing following error.

нет соответствующей функции для вызова 'std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, void*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, void*> > >::insert(std::string&, void*)'

Может кто-нибудь, пожалуйста, помогите мне, как решить эту проблему. Есть ли лучший способ сделать это с помощью STL

Ответы [ 9 ]

22 голосов
/ 03 ноября 2010

Я напечатал этот текст, чтобы сделать его более читабельным ...

typedef std::map<std::string, MyObj*> MyMap;
typedef std::pair<std::string, MyObj*> MyPair;

MyMap myMap;
string strFilename = "MyFile";
MyObj* pObj = new MyObj();
myMap.insert(MyPair(strFilename, pObj));
13 голосов
/ 03 ноября 2010

std :: map требуется пара при использовании функции вставки.

У вас есть два варианта:

myMap[strFileName] = pObj;

Или:

myMap.insert(std::make_pair(strFileName,pObj));
7 голосов
/ 03 ноября 2010

myMap.insert (strFileName, pObj);

Использование make_pair() внутри insert()

#include <utility>
//...
myMap.insert (std::make_pair(strFileName, pObj) ) ;
3 голосов
/ 03 ноября 2010

Нет элемента insert, который принимает ключ и значение в качестве аргумента. Просто используйте оператор индекса:

myMap[fileName] = obj;
2 голосов
/ 03 ноября 2010

Вставить хочет пару, попробуйте что-то вроде этого:

mymap.insert ( pair<string,MyObj*>(strFilename,pObj) );
2 голосов
/ 03 ноября 2010
map<string,MyObj*> myMap;

string strFilename = "MyFile";  
MyObj* pObj = new MyObj();

myMap[strFilename] = pObj;

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

1 голос
/ 26 ноября 2010

Попробуйте boost :: ptr_map (из библиотеки boost :: ptr_container). А с библиотекой boost :: assign вам даже не нужно вызывать new вручную:

class MyObj {
    MyObj() { /* some... */ }
};

typedef boost::ptr_map< string, MyObj > MyMap;
MyMap m;

using namespace boost::assign;

ptr_map_insert( m )( "first" )( "second" )( "third" );

В этом случае в m будет добавлено три элемента (с ключами «first», «second» и «third» и с тремя созданными объектами MyObj ()).

Или:

class MyObj {
    MyObj( int _i ) : i( _i ) { /* some... */ }
    int i;
};

typedef boost::ptr_map< string, MyObj > MyMap;
MyMap m;

using namespace boost::assign;

ptr_map_insert( m )( "first", 1 )( "second", 2 )( "third", 3 );

В этом случае три элемента будут добавлены в m. Первый элемент имеет ключ «first» и значение MyObj (1), второй - «second» и MyObj (2), третий - «третий» и MyObj (3).

0 голосов
/ 26 ноября 2010

Попробуйте boost :: ptr_map ()

0 голосов
/ 03 ноября 2010

Вы звоните insert() неправильно. Он не принимает ключ и значение отдельно, он принимает пару следующим образом:


myMap.insert(pair &lt string, MyObj* &gt (strFileName, pObj));
...