Related
I need to create a unit which represents pressure per time, specifically Bar per Minute.
I tried creating it in the same way as I created similar units before:
typedef boost::units::derived_dimension<boost::units::length_base_dimension, -1,
boost::units::mass_base_dimension, 1,
boost::units::time_base_dimension, -3>::type pressure_roc_dimension;
typedef boost::units::unit<pressure_roc_dimension,
boost::units::make_system<boost::units::metric::bar_base_unit,
boost::units::metric::minute_base_unit>::type> bar_per_minute_unit;
BOOST_UNITS_STATIC_CONSTANT(BarPerMinute, bar_per_minute_unit::unit_type);
typedef boost::units::quantity<bar_per_minute_unit, double> BarPerMinuteRoC;
And then I try to use it:
BarPerMinuteRoC bpm = 5.0 * BarPerMinute;
But this line doesn't compile with quite a long error trail which I'm having a bit of trouble understanding fully.
1>c:\workspace\externals\boost_1_57_0\include\boost\units\detail\linear_algebra.hpp(197): error C2039: 'item' : is not a member of 'boost::units::dimensionless_type'
1> c:\workspace\externals\boost_1_57_0\include\boost\units\dimensionless_type.hpp(37) : see declaration of 'boost::units::dimensionless_type'
1> c:\workspace\externals\boost_1_57_0\include\boost\units\detail\linear_algebra.hpp(259) : see reference to class template instantiation 'boost::units::detail::determine_extra_equations_skip_zeros_impl<true,false>::apply<RowsBegin,1,1,3,Result>' being compiled
1> with
1> [
1> RowsBegin=boost::units::list<boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::detail::make_zero_vector<0>::type>>,boost::units::detail::determine_extra_equations_skip_zeros_impl<false,true>::apply<boost::units::list<boost::units::list<boost::units::static_rational<-1,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::list<boost::units::static_rational<-2,1>,boost::units::detail::expand_dimensions<0>::apply<boost::units::dimensionless_type,boost::units::dimensionless_type>::type>>>,boost::units::dimensionless_type>,1,0,3,boost::units::list<boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::detail::make_zero_vector<0>::type>>>,boost::units::list<boost::units::list<boost::units::static_rational<-1,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::list<boost::units::static_rational<-2,1>,boost::units::detail::expand_dimensions<0>::apply<boost::units::dimensionless_type,boost::units::dimensionless_type>::type>>>,boost::units::dimensionless_type>>>::next_equations>
1> , Result=boost::units::list<boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::detail::make_zero_vector<0>::type>>>,boost::units::list<boost::units::list<boost::units::static_rational<-1,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::list<boost::units::static_rational<-2,1>,boost::units::detail::expand_dimensions<0>::apply<boost::units::dimensionless_type,boost::units::dimensionless_type>::type>>>,boost::units::dimensionless_type>>
1> ]
1> c:\workspace\externals\boost_1_57_0\include\boost\units\detail\linear_algebra.hpp(264) : see reference to class template instantiation 'boost::units::detail::determine_extra_equations<2,false>::apply<boost::units::list<boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::detail::make_zero_vector<0>::type>>,boost::units::detail::determine_extra_equations_skip_zeros_impl<false,true>::apply<boost::units::list<boost::units::list<boost::units::static_rational<-1,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::list<boost::units::static_rational<-2,1>,boost::units::detail::expand_dimensions<0>::apply<boost::units::dimensionless_type,boost::units::dimensionless_type>::type>>>,boost::units::dimensionless_type>,1,0,3,Result>::next_equations>,3,Result>' being compiled
1> with
1> [
1> Result=boost::units::list<boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::detail::make_zero_vector<0>::type>>>,boost::units::list<boost::units::list<boost::units::static_rational<-1,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::list<boost::units::static_rational<-2,1>,boost::units::detail::expand_dimensions<0>::apply<boost::units::dimensionless_type,boost::units::dimensionless_type>::type>>>,boost::units::dimensionless_type>>
1> ]
1> c:\workspace\externals\boost_1_57_0\include\boost\units\detail\linear_algebra.hpp(538) : see reference to class template instantiation 'boost::units::detail::determine_extra_equations<3,false>::apply<Matrix,3,Matrix>' being compiled
1> with
1> [
1> Matrix=boost::units::list<boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::detail::make_zero_vector<0>::type>>>,boost::units::list<boost::units::list<boost::units::static_rational<-1,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::list<boost::units::static_rational<-2,1>,boost::units::detail::expand_dimensions<0>::apply<boost::units::dimensionless_type,boost::units::dimensionless_type>::type>>>,boost::units::dimensionless_type>>
1> ]
1> c:\workspace\externals\boost_1_57_0\include\boost\units\detail\linear_algebra.hpp(828) : see reference to class template instantiation 'boost::units::detail::make_square_and_invert<boost::units::list<boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<0,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::detail::make_zero_vector<0>::type>>>,boost::units::list<boost::units::list<boost::units::static_rational<-1,1>,boost::units::list<boost::units::static_rational<1,1>,boost::units::list<boost::units::static_rational<-2,1>,boost::units::detail::expand_dimensions<0>::apply<boost::units::dimensionless_type,boost::units::dimensionless_type>::type>>>,boost::units::dimensionless_type>>>' being compiled
1> c:\workspace\externals\boost_1_57_0\include\boost\units\detail\linear_algebra.hpp(1032) : see reference to class template instantiation 'boost::units::detail::normalize_units<T>' being compiled
1> with
1> [
1> T=boost::units::list<boost::units::scaled_base_unit<boost::units::si::second_base_unit,boost::units::scale<60,boost::units::static_rational<1,1>>>,boost::units::list<boost::units::metric::bar_base_unit,boost::units::dimensionless_type>>
1> ]
1> c:\workspace\externals\boost_1_57_0\include\boost\units\detail\linear_algebra.hpp(1051) : see reference to class template instantiation 'boost::units::detail::calculate_base_unit_exponents_impl<false>::apply<T,Dimensions>' being compiled
1> with
1> [
1> T=boost::units::list<boost::units::scaled_base_unit<boost::units::si::second_base_unit,boost::units::scale<60,boost::units::static_rational<1,1>>>,boost::units::list<boost::units::metric::bar_base_unit,boost::units::dimensionless_type>>
1> , Dimensions=BSII::Units::pressure_roc_dimension
1> ]
1> c:\workspace\externals\boost_1_57_0\include\boost\units\heterogeneous_system.hpp(243) : see reference to class template instantiation 'boost::units::detail::calculate_base_unit_exponents<boost::units::list<boost::units::scaled_base_unit<boost::units::si::second_base_unit,boost::units::scale<60,boost::units::static_rational<1,1>>>,boost::units::list<T,boost::units::dimensionless_type>>,Dimensions>' being compiled
1> with
1> [
1> T=boost::units::metric::bar_base_unit
1> , Dimensions=BSII::Units::pressure_roc_dimension
1> ]
1> c:\workspace\externals\boost_1_57_0\include\boost\units\unit.hpp(92) : see reference to class template instantiation 'boost::units::detail::make_heterogeneous_system<Dim,System>' being compiled
1> with
1> [
1> Dim=BSII::Units::pressure_roc_dimension
1> , System=boost::units::homogeneous_system<boost::units::list<boost::units::scaled_base_unit<boost::units::si::second_base_unit,boost::units::scale<60,boost::units::static_rational<1,1>>>,boost::units::list<boost::units::metric::bar_base_unit,boost::units::dimensionless_type>>>
1> ]
1> c:\workspace\externals\boost_1_57_0\include\boost\units\unit.hpp(99) : see reference to class template instantiation 'boost::units::reduce_unit<S1>' being compiled
1> with
1> [
1> S1=BSII::Units::bar_per_minute_unit
1> ]
1> c:\workspace\foundations\sw_foundations\bsii_common\test\src\units\units_pressure_test.cpp(97) : see reference to class template instantiation 'boost::units::is_implicitly_convertible<BSII::Units::bar_per_minute_unit,Unit>' being compiled
1> with
1> [
1> Unit=BSII::Units::bar_per_minute_unit
1> ]
According to the Boost documentation a homogeneous system can only be composed of linearly independent base units. In my case, I'm trying to mix bars (which in turn "contain" seconds as the time element) with minutes. This sounds problematic to me. But on the other hand, since I don't include mass and length base units in my system it seems to me that the base is independent after all.
In any case, I searched online for an example of creating such a heterogeneous unit but didn't find anything comprehensible. Also, I read in the Boost documentation that a heterogeneous unit doesn't perserve information about how it was created. Does this mean I won't be able to, for instance, multiply BarPerMinuteRoC by Minute and get Bar back?
This is a bug in the library. Your code ought to work and it does in the current GIT develop branch.
This code fails to build in VC2013: (EDIT: I'm not asking why it fails to build)
#include <functional>
struct MyStruct
{
std::function<void()> m_Func;
MyStruct( const std::function<void()>& func) : m_Func(func) {}
};
int main()
{
MyStruct rc( NULL );
return 0;
}
With error:
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(283): error C2064: term does not evaluate to a function taking 0 arguments
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(228) : see reference to function template instantiation '_Ret std::_Callable_obj<int,false>::_ApplyX<_Rx,>(void)' being compiled
1> with
1> [
1> _Ret=void
1> , _Rx=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(228) : see reference to function template instantiation '_Ret std::_Callable_obj<int,false>::_ApplyX<_Rx,>(void)' being compiled
1> with
1> [
1> _Ret=void
1> , _Rx=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(226) : while compiling class template member function 'void std::_Func_impl<_MyWrapper,_Alloc,_Ret,>::_Do_call(void)'
1> with
1> [
1> _Alloc=std::allocator<std::_Func_class<void,>>
1> , _Ret=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(495) : see reference to class template instantiation 'std::_Func_impl<_MyWrapper,_Alloc,_Ret,>' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_Func_class<void,>>
1> , _Ret=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(396) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> , _Fty=int
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(396) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> , _Fty=int
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(385) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,>>>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Fty=int
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(385) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,>>>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Fty=int
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset<_Ty>(_Fty &&)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Fty=int
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset<_Ty>(_Fty &&)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Fty=int
1> ]
1> f:\work\teststdfunction\teststdfunction.cpp(16) : see reference to function template instantiation 'std::function<void (void)>::function<int>(_Fx &&)' being compiled
1> with
1> [
1> _Fx=int
1> ]
1> f:\work\teststdfunction\teststdfunction.cpp(16) : see reference to function template instantiation 'std::function<void (void)>::function<int>(_Fx &&)' being compiled
1> with
1> [
1> _Fx=int
1> ]
(Note the '_Fx=int' at the last two reported errors).
I can live with that, as changing MyStruct rc(NULL) to MyStruct rc(nullptr) solves the error. Two things however remain a mystery:
1) Removing the const qualifier from MyStruct ctor (MyStruct( std::function<void()>& func) gives a very, very different error:
1>f:\work\main\dev\common\teststdfunction\teststdfunction\teststdfunction.cpp(16):
error C2664: 'MyStruct::MyStruct(const MyStruct &)' : cannot convert
argument 1 from 'int' to 'std::function &'
Which makes more sense than the original error, and now fixing NULL to nullptr doesn't solve it. Why does int (or nullptr) refuse to cast to std::function<>& but agree to cast to a const std::function<>& ?
2) The original code compiles and works as expected in VS2010. Is it an obscure VS2010 library bug?
EDIT:
As far as the const/non const question goes, I now think the casting involved and potential type mismatch are probably a red herring. The argument passed - either NULL or nullptr - is a literal and thus a const. It just cannot bind to a non const reference. For example:
const int& a = 8; // Ok
int& b = 9; // error C2440: 'initializing' : cannot convert from 'int' to 'int &'
Does that sound right? Am I still missing something?
The special here has to do with constructor template constraints and other implicit conversions.
The reason why nullptr works is because std::function has a particular constructor taking it. This constructor will always be the best match for that argument because function templates are ranked as lower preference, all else being equal.
Normally, 0 will implicitly convert to nullptr and that's fine. The problem is that it can also be passed to the unconstrained function template constructor which constructs from function objects. This does not require an implicit conversion, so all is not equal, so this constructor is preferred- which results in the error that you see that int is not a valid function object.
libstdc++ and libc++ don't not exhibit this behaviour because they have implemented the C++14 fix for this problem, which constrains the constructor. C++11 did not so this behaviour is quite conforming for a C++11 implementation.
This kind of issue is why NULL is a terrible thing that you shouldn't use. In fact, the VS2010 team had to rush nullptr out the door as an additional feature in the last minute because NULL interacts so badly with every other feature in C++, ever, and especially with C++11.
For const vs non-const references, other answers have explained that issue adequately.
There are other WTFs you can find when using std::function without the constrained constructor fix shipped in C++14- this isn't the only one. The long and short is that it's a defect in the C++11 Standard, and not in VS. VS2010 compiling it is probably a compiler overload resolution bug.
Casting a T to a U& never works, and that's intentionally. You can cast to a U const&. The reason is that changes to the temporary U object wouldn't propagate back to the T value.
VS2010 is slightly buggy in this respect, and did allow the cast (but with the proper settings, will warn about it)
i have map that looks like this:
typedef std::map<PuzzlePartLocation, std::shared_ptr<PuzzleObj>> ComponentsMap;
now i try to set this map with elements via fucntion like this:
void ComponentMadiator::Register(const PuzzlePartLocation puzzlePartLocation,PuzzleObj* puzzleObj)
{
componentsMap[puzzlePartLocation] = std::make_shared<PuzzleObj>(puzzleObj);
}
i just call it like this :
PuzzleObj* pPuzzleObjStickLeft = new PuzzleObj()
pComponentMadiator->Register(1,pPuzzleObjStickLeft );
PuzzleObj contains memeber from type IImageComponent *
PuzzleObj inherits from base class
but it give me error like this :
1>c:\program files\microsoft visual studio 11.0\vc\include\memory(873): error C2664: 'PuzzleObj::PuzzleObj(IImageComponent *)' : cannot convert parameter 1 from 'PuzzleObj *' to 'IImageComponent *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1> c:\program files\microsoft visual studio 11.0\vc\include\memory(972) : see reference to function template instantiation 'std::_Ref_count_obj<_Ty>::_Ref_count_obj<PuzzleObj*&>(_V0_t)' being compiled
1> with
1> [
1> _Ty=PuzzleObj,
1> _V0_t=PuzzleObj *&
1> ]
1> c:\program files\microsoft visual studio 11.0\vc\include\memory(972) : see reference to function template instantiation 'std::_Ref_count_obj<_Ty>::_Ref_count_obj<PuzzleObj*&>(_V0_t)' being compiled
1> with
1> [
1> _Ty=PuzzleObj,
1> _V0_t=PuzzleObj *&
1> ]
1> d:\dev\cpp\cocos2d-x\cocos2d-x-3.0beta2\cocos2d-x-3.0beta2\projects\neonbreaker\classes\componentmadiator.cpp(23) : see reference to function template instantiation 'std::shared_ptr<_Ty> std::make_shared<PuzzleObj,PuzzleObj*&>(_V0_t)' being compiled
1> with
1> [
1> _Ty=PuzzleObj,
1> _V0_t=PuzzleObj *&
1> ]
std::make_shared<PuzzleObj> creates a new PuzzleObj for you. What you need is std::shared_ptr<PuzzleObj>(puzzleObj).
More importantly
void ComponentMadiator::Register(const PuzzlePartLocation puzzlePartLocation,PuzzleObj* puzzleObj);
should be declared as:
void ComponentMadiator::Register(const PuzzlePartLocation puzzlePartLocation, std::shared_ptr<PuzzleObj> const& puzzleObj);
because it shares ownership of puzzleObj by storing it in the container and that must be communicated in function's interface.
And call it like so:
std::shared_ptr<PuzzleObj> pPuzzleObjStickLeft(std::make_shared<PuzzleObj>());
pComponentMadiator->Register(1, pPuzzleObjStickLeft);
Is this a Boost bug or am I doing something wrong?
#include <map>
#include <boost/pool/pool_alloc.hpp>
int main()
{
typedef const std::string key;
typedef double* (*value)(const int&);
std::map<key, value, std::less<key>> map_with_standard_allocator; // works
std::map<key, value, std::less<key>, boost::fast_pool_allocator<std::pair<const key, value> > > map_with_boost_allocator; // fails
}
the last line fails to compile under MS Visual Studio 2008 with Boost 1.40 and 1.48. It compiles fine under g++ 4.5.3 (Cygwin), though.
The error is:
1>Compiling...
1>main.cpp
1>C:\UniLib1\trunk\External\boost/pool/pool_alloc.hpp(205) : error C2535: 'const std::basic_string<_Elem,_Traits,_Ax> *boost::fast_pool_allocator<T,UserAllocator,Mutex,NextSize>::address(const std::basic_string<_Elem,_Traits,_Ax> &)' : member function already defined or declared
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>,
1> T=const std::basic_string<char,std::char_traits<char>,std::allocator<char>>,
1> UserAllocator=boost::default_user_allocator_new_delete,
1> Mutex=boost::details::pool::default_mutex,
1> NextSize=32
1> ]
1> C:\UniLib1\trunk\External\boost/pool/pool_alloc.hpp(202) : see declaration of 'boost::fast_pool_allocator<T,UserAllocator,Mutex,NextSize>::address'
1> with
1> [
1> T=const std::basic_string<char,std::char_traits<char>,std::allocator<char>>,
1> UserAllocator=boost::default_user_allocator_new_delete,
1> Mutex=boost::details::pool::default_mutex,
1> NextSize=32
1> ]
1> c:\Program Files\Microsoft Visual Studio 9.0\VC\include\xtree(137) : see reference to class template instantiation 'boost::fast_pool_allocator<T,UserAllocator,Mutex,NextSize>' being compiled
1> with
1> [
1> T=const std::basic_string<char,std::char_traits<char>,std::allocator<char>>,
1> UserAllocator=boost::default_user_allocator_new_delete,
1> Mutex=boost::details::pool::default_mutex,
1> NextSize=32
1> ]
1> c:\Program Files\Microsoft Visual Studio 9.0\VC\include\map(78) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
1> with
1> [
1> _Traits=std::_Tmap_traits<key,value ,std::less<key>,boost::fast_pool_allocator<std::pair<key,value >>,false>
1> ]
1> .\main.cpp(9) : see reference to class template instantiation 'std::map<_Kty,_Ty,_Pr,_Alloc>' being compiled
1> with
1> [
1> _Kty=key,
1> _Ty=value,
1> _Pr=std::less<key>,
1> _Alloc=boost::fast_pool_allocator<std::pair<key,value >>
1> ]
This is not a bug in VS2008 (as I mistakenly claimed in an earlier edit to this answer). The C++03 standard requires that the key type for an associative container, like std::map, must be 'assignable' (per Table 69 in 23.1.2 "Associative containers"). And a const std::string is not assignable. Note that the C++11 standard seems to relax this requirement, but the new standard doesn't apply to since VC++ 2008.
It's not clear to me that a compiler is required to diagnose code that tries to use std::map with a non-assignable key, so I don't think one can claim that GCC or VC++ 2010 are accepting this code improperly (I think it falls into the area of undefined code that works as you might expect, even though there's no guarantee it'll work). However it is clear that it's OK for VC++ 2008 to refuse to compile it.
All that said, I think that VC++ 2008's library parameterizing the allocator's address() function on the map's key rather than map's element is still suspect (see the first edit of this answer for details if you're interested), but I don't think there's any real bug there since the std::pair<> used to hold the map element will always be set up such that key part will be at the same address as the whole element.
I need a data structure, and I'm unsure of what to choose. Fundamentally, my need is similar to std::set, except I need to look up according to multiple different comparators over the same data at the same time.
Right now I've decided to go for some kludge- a std::map<float, std::unordered_set<T>> and then a std::unordered_map<T, std::unordered_set<T>*>. This should permit O(log N) lookup for a float and O(1) lookup/removal for a T.
Are there any better data structures to use? This has "hack" written all over it.
As an aside, this code is fairly performance critical, so something fast would be very appreciated.
Edit: I've been poking with boost::multi_index and here's what I've got so far:
boost::multi_index_container<
NodeType,
boost::multi_index::indexed_by<
boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>, decltype(node_comparator)>,
boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>
>
> open_set(
boost::make_tuple(node_comparator)
);
where node_comparator is an in_scope lambda. But attempting to compile it results in some glorious errors.
1>d:\backups\code\boost_1_47_0\boost\multi_index\detail\node_type.hpp(56): error C2903: 'node_class' : symbol is neither a class template nor a function template
1> d:\backups\code\boost_1_47_0\boost\mpl\aux_\preprocessed\plain\apply_wrap.hpp(49) : see reference to class template instantiation 'boost::multi_index::detail::index_node_applier::apply<IndexSpecifierIterator,Super>' being compiled
1> with
1> [
1> IndexSpecifierIterator=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0>,
1> Super=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>>
1> ]
1> d:\backups\code\boost_1_47_0\boost\mpl\aux_\preprocessed\plain\bind.hpp(207) : see reference to class template instantiation 'boost::mpl::apply_wrap2<F,T1,T2>' being compiled
1> with
1> [
1> F=boost::multi_index::detail::index_node_applier,
1> T1=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0>,
1> T2=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>>
1> ]
1> d:\backups\code\boost_1_47_0\boost\mpl\aux_\preprocessed\plain\apply_wrap.hpp(49) : see reference to class template instantiation 'boost::mpl::bind2<F,T1,T2>::apply<U1,U2>' being compiled
1> with
1> [
1> F=boost::multi_index::detail::index_node_applier,
1> T1=boost::mpl::_2,
1> T2=boost::mpl::_1,
1> U1=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>>,
1> U2=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0>
1> ]
1> d:\backups\code\boost_1_47_0\boost\mpl\aux_\preprocessed\plain\apply.hpp(63) : see reference to class template instantiation 'boost::mpl::apply_wrap2<F,T1,T2>' being compiled
1> with
1> [
1> F=boost::mpl::bind2<boost::multi_index::detail::index_node_applier,boost::mpl::_2,boost::mpl::_1>,
1> T1=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>>,
1> T2=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0>
1> ]
1> d:\backups\code\boost_1_47_0\boost\mpl\aux_\preprocessed\plain\reverse_iter_fold_impl.hpp(82) : see reference to class template instantiation 'boost::mpl::apply2<F,T1,T2>' being compiled
1> with
1> [
1> F=boost::mpl::bind2<boost::multi_index::detail::index_node_applier,boost::mpl::_2,boost::mpl::_1>,
1> T1=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>>,
1> T2=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0>
1> ]
1> d:\backups\code\boost_1_47_0\boost\mpl\reverse_iter_fold.hpp(43) : see reference to class template instantiation 'boost::mpl::aux::reverse_iter_fold_impl<N,First,Last,State,BackwardOp,ForwardOp>' being compiled
1> with
1> [
1> N=2,
1> First=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0>,
1> Last=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,2>,
1> State=boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>,
1> BackwardOp=boost::mpl::bind2<boost::multi_index::detail::index_node_applier,boost::mpl::_2,boost::mpl::_1>,
1> ForwardOp=boost::mpl::protect<boost::mpl::arg<1>>
1> ]
1> d:\backups\code\boost_1_47_0\boost\multi_index\detail\node_type.hpp(70) : see reference to class template instantiation 'boost::mpl::reverse_iter_fold<Sequence,State,BackwardOp>' being compiled
1> with
1> [
1> Sequence=boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,
1> State=boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>,
1> BackwardOp=boost::mpl::bind2<boost::multi_index::detail::index_node_applier,boost::mpl::_2,boost::mpl::_1>
1> ]
1> d:\backups\code\boost_1_47_0\boost\multi_index_container.hpp(75) : see reference to class template instantiation 'boost::multi_index::detail::multi_index_node_type<Value,IndexSpecifierList,Allocator>' being compiled
1> with
1> [
1> Value=NodeType,
1> IndexSpecifierList=boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,
1> Allocator=std::allocator<NodeType>
1> ]
1> c:\repo\render\render\sim\simcontext.cpp(264) : see reference to class template instantiation 'boost::multi_index::multi_index_container<Value,IndexSpecifierList>' being compiled
1> with
1> [
1> Value=NodeType,
1> IndexSpecifierList=boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>
1> ]
This is just the first; there are many, but I'm well aware of Visual Studio's propensity to let one error cause 9999999 more.
One thing you can try is to use a weak_ptr in your unordered_set, and shared_ptr for your elements. When you destruct the element, a NULL weak_ptr is left behind. You would need some way to garbage collect those NULL weak_ptr entries in your container, but that cost is likely easily amortized. This way, you avoid needing to use a second index at all.
multi_index was the winner. Unfortunately dirkgently posted as comment, not answer, or I'd accept it.