проблема константности при вставке в std :: map

У меня возникла проблема с константностью при попытке вставить пару в карту. Ошибка компилятора:

              c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(2089) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> &std::pair<_Ty1,_Ty2>::operator =(const std::pair<_Ty1,_Ty2> &)' being compiled
1>          with
1>          [
1>              _Ty1=const Assets::AssetId,
1>              _Ty2=std::shared_ptr<Assets::Material>
1>          ]
1>          c:\fusionengine\meshgl.cpp(85) : see reference to class template instantiation 'std::pair<_Ty1,_Ty2>' being compiled
1>          with
1>          [
1>              _Ty1=const Assets::AssetId,
1>              _Ty2=std::shared_ptr<Assets::Material>
1>          ]

Строка, вызывающая ошибку:

m_materials.insert( MaterialsMap::value_type(pMaterial->AssetId(), pMaterial) );

Карта m_materials объявлена ​​следующим образом:

typedef std::map< Assets::AssetId, std::shared_ptr<Material> > MaterialsMap;
typedef std::pair< Assets::AssetId, std::shared_ptr<Material> > MtlPair;

MaterialsMap  m_materials;

Ошибка 1 ошибка C2166: l-значение указывает const-объект c: \ program files (x86) \ microsoft visual studio 11.0 \ vc \ include \ utility 114

Может кто-нибудь объяснить, как я решаю эту проблему?

2

Решение

Этот код компилируется нормально с GCC:

#include <map>
#include <memory>
using namespace std;

typedef int AssetId;
struct Material {
int _id;
Material(int id) : _id(id) {}
int AssetId() const { return _id; }
};
typedef std::map< AssetId, std::shared_ptr<Material> > MaterialsMap;

MaterialsMap  m_materials;

int main() {
std::shared_ptr<Material> pMaterial(new Material(42));
m_materials.insert( MaterialsMap::value_type(pMaterial->AssetId(), pMaterial) );
}

Либо ваш пример неполон, либо неверен, или это ошибка в реализации стандартной библиотеки MSVC2012. Это не должны вызов operator= в приведенном выше коде.

2

Другие решения

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

Эта проблема не была связана с компилятором, хотя сообщения об ошибках могли быть связаны с улучшением, хотя я понимаю, что это всегда было проблемой с шаблоном (и STL) кода.

Поэтому у меня была перегрузка std :: copy в моей перегрузке operator =, чтобы скопировать содержимое одной карты в другую. Мало ли я знал, что это нет-нет.

Я наконец выяснил это, построив весь класс снова, построчно и функция за функцией, чтобы изолировать проблемную область.

Затем, изучив проблемную область и поиск в Google, на помощь пришло stackoverflow. вопрос и ответ.

Хотя следующее утверждение недопустимо, оно не выделяется как ошибка в IDE VS2012, и компилятор не определяет его как утверждение проблемы.

std::copy( map1.begin(), map1.end(), map2.begin() );

Как указывалось в ранее выделенном ответе SO, правильный способ сделать это с помощью оператора вставки:

map2.insert( map1.begin(), map1.end() );

Я надеюсь, что это помогает кому-то там 🙂

3

По вопросам рекламы [email protected]