0

I am trying to iterate over a multimap<int, weak_ptr<RenderObject>> but for some reason using the for loop below causes an error.

using RenderIndex = int32_t;
class RenderObject
{
public:
   RenderIndex m_render_index;
   // rest of class definition
};

std::multimap<RenderIndex, std::weak_ptr<RenderObject>> m_render_objects;
for (auto renderPair : m_render_objects) // error occurs here
{
    // call render function..
}

The error visual studio complains about is l-value specifies const object. After looking through the error output in vs I think the problem is from the weak_ptr<> as if I try the same thing but with a shared_ptr as the value in the map there are no errors.

My question is if my hypothesis is correct that the weak_ptr<> is causing the error what is the reason/explanation for this behaviour?

I could always use a list of weak_ptr as this does not seem to have the same issue but I want to have the RenderObject sorted based on render order and a map gives this by default whereas a list would require a resort on each insertion/change/removal which would be very inefficient.

Console Output:

1>------ Build started: Project: Engine, Configuration: Debug x64 ------
1>RenderLayer.cpp
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.11.25503\include\utility(246): error C2166: l-value specifies const object
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.11.25503\include\utility(245): note: while compiling class template member function 'std::pair<const _Kty,_Ty> &std::pair<const _Kty,_Ty>::operator =(std::pair<const _Kty,_Ty> &&) noexcept(false)'
1>        with
1>        [
1>            _Kty=otw::RenderIndex,
1>            _Ty=std::weak_ptr<otw::RenderObject>
1>        ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.11.25503\include\algorithm(1325): note: see reference to function template instantiation 'std::pair<const _Kty,_Ty> &std::pair<const _Kty,_Ty>::operator =(std::pair<const _Kty,_Ty> &&) noexcept(false)' being compiled
1>        with
1>        [
1>            _Kty=otw::RenderIndex,
1>            _Ty=std::weak_ptr<otw::RenderObject>
1>        ]
1>c:\outlaw\outlaw_games_engine\engine\renderlayer.cpp(13): note: see reference to class template instantiation 'std::pair<const _Kty,_Ty>' being compiled
1>        with
1>        [
1>            _Kty=otw::RenderIndex,
1>            _Ty=std::weak_ptr<otw::RenderObject>
1>        ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.11.25503\include\xstring(2007): note: see reference to function template instantiation 'std::_String_alloc<std::_String_base_types<_Elem,_Alloc>>::_String_alloc<const _Alloc&,void>(_Any_alloc)' being compiled
1>        with
1>        [
1>            _Elem=wchar_t,
1>            _Alloc=std::allocator<wchar_t>,
1>            _Any_alloc=const std::allocator<wchar_t> &
1>        ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.11.25503\include\xstring(2006): note: see reference to function template instantiation 'std::_String_alloc<std::_String_base_types<_Elem,_Alloc>>::_String_alloc<const _Alloc&,void>(_Any_alloc)' being compiled
1>        with
1>        [
1>            _Elem=wchar_t,
1>            _Alloc=std::allocator<wchar_t>,
1>            _Any_alloc=const std::allocator<wchar_t> &
1>        ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.11.25503\include\string(516): note: see reference to function template instantiation 'std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>::basic_string<_Elem*,void>(_Iter,_Iter,const _Alloc &)' being compiled
1>        with
1>        [
1>            _Elem=wchar_t,
1>            _Iter=wchar_t *,
1>            _Alloc=std::allocator<wchar_t>
1>        ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.11.25503\include\string(516): note: see reference to function template instantiation 'std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>::basic_string<_Elem*,void>(_Iter,_Iter,const _Alloc &)' being compiled
1>        with
1>        [
1>            _Elem=wchar_t,
1>            _Iter=wchar_t *,
1>            _Alloc=std::allocator<wchar_t>
1>        ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.11.25503\include\string(596): note: see reference to function template instantiation 'std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> std::_Integral_to_string<wchar_t,int>(const _Ty)' being compiled
1>        with
1>        [
1>            _Ty=int
1>        ]
1>Done building project "Engine.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

EDIT

I have tried for(const auto& renderPair : m_render_objects) and for(auto& renderPair : m_render_objects). Also for and while loop variations using the iterator. All of which produce the exact same error.

NOTE

I am using Visual Studio 2017 with C++17.

Matthew
  • 800
  • 3
  • 12
  • 35
  • 1
    Try `for (auto& renderPair : m_render_objects)` –  Jan 21 '18 at 16:37
  • @user9212993 I have actually already tried that. I produces the exact same error. I have updated my question to include my previous attempts to resolve the error – Matthew Jan 21 '18 at 16:42
  • 1
    Provide a [MCVE] that reproduces your exact error please! –  Jan 21 '18 at 16:44
  • @user9212993 I do not see how this is not a minimal, complete, and verifiable example. It provides the error output, the code that causes the problem and the required class definitions. I could add a tone more information but then that would not be minimal. Please give more information as to what you need to help. – Matthew Jan 21 '18 at 16:46
  • Well, I can't reproduce the error from the code you posted: http://coliru.stacked-crooked.com/a/2d43df04220ca1e1 –  Jan 21 '18 at 16:50
  • I added in every relevant class definition removing getter setters and other methods that are irrelevant. this should help – Matthew Jan 21 '18 at 16:52
  • Can you show what is in line 13 on file: c:\outlaw\outlaw_games_engine\engine\renderlayer.cpp? – Amadeus Jan 21 '18 at 17:02
  • @Amadeus line 13 is the `for (auto renderPair : m_render_objects) // error occurs here` – Matthew Jan 21 '18 at 17:05
  • 1
    As said above, please provide a minimal, complete and verifiable example. Such an example is one that I can simply copy-paste it on my machine and compile it. Currently your snippets don't fulfill this. I need to put them together and in the process try to figure what headers do I need to include(e.g. what is STRCODE and where is it declared). If you have dependencies on non-standard headers, change your class to something dummy in order to remove dependencies, this may actually may help you find the error. I hope now you see why your code is not minimal, complete and verifiable. – opetroch Jan 21 '18 at 17:26
  • Looks more like a problem with your map key class RenderIndex. There is some problem with a std::string copy/assignment. Try to double-clich the notes in the error message to see rhe context – Mihayl Jan 21 '18 at 17:52
  • @A.A RenderIndex is just a type alias for `std::size_t`. – Matthew Jan 21 '18 at 19:17
  • @user9212993 I updated the question so that it has definitions for STRCODE and RenderIndex – Matthew Jan 21 '18 at 19:18
  • @Matthew What's so hard to get about [MCVE] actually? –  Jan 21 '18 at 19:22
  • @user9212993 If this edit still is not enough then I am truly lost. – Matthew Jan 21 '18 at 19:31
  • @Matthew Why don't you simply following the instructions from that link I provided multiple times for you now? Doing so might already be helpful to solve that problem yourself. What you added is useless in regard of what I've been asking for. –  Jan 21 '18 at 19:35
  • @Matthew an [mcve] is a code that I can paste on my machine, compile it and found the same issue you are having. The code you provide does not allow this – Amadeus Jan 21 '18 at 19:35
  • @Amadeus I understand what you mean now. Thank you for the input. I just figured out what the problem was. I did not realize that you can't use `std::remove_if` on a map and for whatever reason, it errors on the loop above and not on the remove_if. That would be why you couldn't reproduce it on your machine. for the future, I will test my code snippet on something such as compiler explorer and ensure it is receiving the same error. thank you for the help – Matthew Jan 21 '18 at 19:40

0 Answers0