We have a problem porting our code to the slightly less old version 2010 of VC++.
The issues is caused by the implementation of map in VC which results in a derived to base conversion of a pointer-to-member in a non-type-argument being required:
#include <map>
#include <algorithm>
template <typename MapValueType, int MapValueType::*var>
bool f (MapValueType const & v);
int main ()
{
typedef std :: map<int, int> MapType;
MapType m;
std :: find_if (m.begin ()
, m.end ()
, f<MapType::value_type, & MapType::value_type::second> );
}
The following message is generated:
Standard conversion from pointer-to-member of base to pointer-to-member of derived is not applied for template arguments file.cc(x) : error C2973:
‘f’ : invalid template argument ‘int std::_Pair_base<_Ty1,_Ty2>::* ‘
So it seems that the implementation of value_type in std::map has the pair in a base class.
Any ideas on how to solve this and keep the pointer-to-member as a non-type-argument?
Is our only option to change the structure so that f is a functor with a member pointer-to-member?
Provided that your code should compile IMO (and it does on GCC 4.7.2 and Clang 3.2), I believe your design is unnecessarily intricate. A
paironly has two member variables, so you are going to access either the first or the second.I do not see the need for a functor object either: just use a boolean template argument to determine whether the code shall work on the
firstor on thesecondmember variable.Here’s a possibility:
If you really cannot change your client code nor your code inside the
f()function, then you could go for this VS2010-specific hack:Finally, if your code has to compile on other platforms and all the constraints on the non-modifiability of the function’s and client code still hold, then you can define a preprocessor macro that expands to
_Mybase::for VS2010 and to the empty string for other compilers.