std:: пара std::string и пользовательский класс не удается скопировать на std::map::insert(std::make_pair(строка, класс))

#c #insert #std-pair

#c #вставить #std-pair

Вопрос:

Эта ошибка:

 error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const std::string' (or there is no acceptable conversion)  c:program files (x86)microsoft visual studio 10.0vcincludeutility  216
  

происходит в единственной строке этой функции:

 void Animation::AddAnimation(std::string name, AnimationFrameSetamp; animation) {
    _animations.insert(std::make_pair(name, animation));
}
  

_animations является ли std::map<std::string, AnimationFrameSet>

AnimationFrameSet объявляет operator=(…) и конструктор копирования, но, как ни странно, компилятор сообщает, что это не удается при попытке копирования const std::string …несмотря на то, что строка даже не передается как const .

Я ни за что на свете не могу понять (или даже вспомнить! :P) почему это / должно вызывать / выдавать ошибку.

Спасибо.

Редактировать

Причина, по которой я немного смущен, почему это не работает, заключается в том, что другой класс использует очень похожую реализацию и не выдает ошибку:

 BITMAP* BitmapCache::GetBitmap(std::string filename) {
    //Return NULL if a bad filename was passed.
    if(filename.empty()) return NULL;
    if(exists(filename.c_str()) == false) return NULL;

    //Reduce incorrect results by forcing slash equality.
    filename = fix_filename_slashes(amp;filename[0]);

    //Clean the cache if it's dirty.
    CleanCache();

    //Search for requested BITMAP.
    MapStrBmpIter _iter = _cache.find(filename);

    //If found, return it.
    if(_iter != _cache.end()) return _iter->second;

    //Otherwise, create it, store it, then return it.
    BITMAP* result = load_bmp(filename.c_str(), NULL);
    if(result == NULL) return NULL;
    /*Similar insert line, a non-const std::string that was passed in is passed to a std::make_pair(...) function*/
    _cache.insert(std::make_pair(filename, result));
    return resu<
}
  

typedefs:

 typedef std::map<std::string, BITMAP*> MapStrBmp;
typedef MapStrBmp::iterator MapStrBmpIter;
  

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

1. Можете ли вы показать нам operator= ? Что произойдет, если вы make_pair явно укажете аргументы типа?

2. Вы включили «#include <строка>»?

3. также попробуйте предоставить минимальный код, который вызывает ту же проблему

4. Основываясь на пути заголовка, я почти уверен, что Visual Studio 2010 выводит больше, чем просто эту строку. Возможно, вы захотите включить это в свой вопрос.

Ответ №1:

Причина, по которой это не удается, заключается в том, что используемый вами контейнер std::map ожидает постоянное значение в качестве значения ключа.

Проверьте документацию std::map здесь.

Пример:

 class TestClass
{
};

std::map< const std::string, TestClass > myMap;
std::pair< const std::string, TestClass > firstElement = std::make_pair("test", TestClass() );
myMap.insert( firstElement );
  

Ответ №2:

Поскольку _animations это std::map , попробуйте использовать другой метод вставки, например:

 _animations[name] = animation;
  

Но более важной вещью для проверки было бы то, имеет ли класс AnimationFrameSet допустимый конструктор копирования и оператор присваивания. Если это не так, вы можете захотеть использовать класс интеллектуального указателя, такой как:

 typedef std::shared_ptr<AnimationFrameSet> AnimationFrameSetPtr;
  

Тогда карта была бы:

 std::map<std::string, AnimationFrameSetPtr>