У меня возникла проблема с константностью при попытке вставить пару в карту. Ошибка компилятора:
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
Может кто-нибудь объяснить, как я решаю эту проблему?
Этот код компилируется нормально с 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=
в приведенном выше коде.
Я сорвал свои волосы из-за этой проблемы, я, вероятно, потратил на это неделю. К счастью, это не было критично для дорожной карты проекта, поэтому это не помешало продолжить.
Эта проблема не была связана с компилятором, хотя сообщения об ошибках могли быть связаны с улучшением, хотя я понимаю, что это всегда было проблемой с шаблоном (и STL) кода.
Поэтому у меня была перегрузка std :: copy в моей перегрузке operator =, чтобы скопировать содержимое одной карты в другую. Мало ли я знал, что это нет-нет.
Я наконец выяснил это, построив весь класс снова, построчно и функция за функцией, чтобы изолировать проблемную область.
Затем, изучив проблемную область и поиск в Google, на помощь пришло stackoverflow. вопрос и ответ.
Хотя следующее утверждение недопустимо, оно не выделяется как ошибка в IDE VS2012, и компилятор не определяет его как утверждение проблемы.
std::copy( map1.begin(), map1.end(), map2.begin() );
Как указывалось в ранее выделенном ответе SO, правильный способ сделать это с помощью оператора вставки:
map2.insert( map1.begin(), map1.end() );
Я надеюсь, что это помогает кому-то там 🙂