[type_traits][multi_index][msvc-7.1] problems with is_const in VC 7.1

Hi, Boost.MultiIndex is failing at master for VC 7.1: http://tinyurl.com/oxflkj6 .\boost\multi_index\identity.hpp(75) : error C2535: 'Type &boost::multi_index::detail::const_identity_base<Type>::operator() (const boost::reference_wrapper<Type> &) const' : member function already defined or declared the problem seemingly being with boost::is_const. The offending code looks like template<typename Type> struct const_identity_base { // produces the error above if Type is not const }; template<typename Type> struct non_const_identity_base { ... }; template<class Type> struct identity: mpl::if_c< is_const<Type>::value, detail::const_identity_base<Type>, detail::non_const_identity_base<Type>
Boost.TypeTraits recently changed its is_const implementation to the very simple template <class T> struct is_const : public false_type {}; template <class T> struct is_const<T const> : public true_type{}; template <class T, size_t N> struct is_const<T const[N]> : public true_type{}; template <class T> struct is_const<T const[]> : public true_type{}; which relies on template partial specialization (supposedly supported by VC 7.1). Yet, seems like const_identity_base is wrongly selected for a non-const Type. Any clues about what might be going on? Thank you, Joaquín M López Muñoz Telefónica

On 15/10/2015 13:22, Joaquin M LópezMuñoz wrote:
Sometimes MSVC-7.1 seems to be happier with a bit more flattened template instantiation chain. Maybe if you SFINAE it with partial specialization of identity it will work. Another option is to use if_<> instead of if_c. It could make MSVC happier. Best, Ion

On 15/10/2015 20:40, Joaquín M LópezMuñoz wrote:
I tried with no luck. It doesn't seem related to is_const, MSVC-7.1 considers both const_ref_global_fun_base::operator()(reference_wrapper<Arg>) overloads exactly equal, even if BOOST_STATIC_ASSERT in that class considers both arguments are not the same. One workaround I've found is to pass one reference_wrapper by const reference and the other one by value: //Note, argument taken by const ref (unchanged) Type operator()( const reference_wrapper< typename remove_reference<Value>::type>& x)const { return operator()(x.get()); } //Note, argument taken by value (changed) Type operator()( reference_wrapper< typename remove_const< typename remove_reference<Value>::type>::type> x)const { return operator()(x.get()); } You could make this conditional to MSVC-7.1, but passing reference_wrapper by value should lead to the same performance, I guess. Best, Ion

Ion Gaztañaga <igaztanaga <at> gmail.com> writes:
Overloads can be only be equal if either Value is not a const type or boost::remove_const is not working... and moreover this was working perfectly fine against former versions of Boost.TypeTraits. The problem happens not only with global_fun but also with identity, which might be easier to analyze. Could you please run this and report the results? #include <boost/multi_index/identity.hpp> #include <boost/type_traits/is_base_and_derived.hpp> #include <iostream> struct X{}; template<typename Type> bool const_identity_base_selected() { return boost::is_base_and_derived< boost::multi_index::detail::const_identity_base<Type>, boost::multi_index::identity<Type>
::value; }
int main() { std::cout<<const_identity_base_selected<int>()<<"\n"; std::cout<<const_identity_base_selected<const int>()<<"\n"; std::cout<<const_identity_base_selected<X>()<<"\n"; std::cout<<const_identity_base_selected<const X>()<<"\n"; } The correct result should be: 0 1 0 1 Thanks for your help, Joaquín M López Muñoz Telefónica

On 16/10/2015 11:14, Joaquin M LópezMuñoz wrote:
MSVC-7.1 outputs the same result. During previous experiments I even checked that is_const<remove_reference<Value> >::value was true inside const_ref_global_fun_base (static asserted) and even that typename remove_const< typename remove_reference<Value>::type>::type was a different type than typename remove_reference<Value>::type But for some reason MSVC fails to see both overloads as different. Best, Ion

Ion Gaztañaga <igaztanaga <at> gmail.com> writes:
It has to be connected with the new version of remove_const, I guess, though this is as simple as it can possibly get... May I abuse your patience and ask you for one more test? What happens if we add a dummy int* = 0 argument to one of the overloads so that the signature is different? Does MSVC still fail to look up things right when the class is used (as opposed to defined)? Thank you Joaquín M López Muñoz Telefónica

On 17/10/2015 11:00, Joaquín M LópezMuñoz wrote:
If a dummy "int * = 0" is added to the second overload all tests except serialization related ones pass ok. Serialization is just missing some Interlocked functions from smart_ptr/detail/sp_interlocked.hpp basic_iarchive.obj : error LNK2019: unresolved external symbol __InterlockedDecr ement referenced in function "public: void __thiscall boost::detail::sp_counted_ base::release(void)" (?release@sp_counted_base@detail@boost@@QAEXXZ) basic_oarchive.obj : error LNK2001: unresolved external symbol __InterlockedDecr ement I have a patch for it and with both patches all multi_index tests pass. Best, Ion

Ion Gaztañaga <igaztanaga <at> gmail.com> writes:
Perfect! Thanks for your help. I'll take care of the overload thing, no need for you to submit any pull request or anything. As for the serialization issue, I understand Robert is taking care of if as it affects all libs using Boost.Serialization, not only this one. Best Joaquín M López Muñoz Telefónica

On 18/10/2015 15:15, Joaquín M LópezMuñoz wrote:
It's related to a dependency of Serialization, located in SmartPtr. Peter is already reviewing the pull request: https://github.com/boostorg/smart_ptr/pull/21/ Best, Ion

Joaquin MLópezMuñoz wrote:
I was waiting for the 7.1 tester to cycle. I see now that it has. None of the tests seem to work though. They fail with shared_ptr_test.cpp ..\libs\smart_ptr\test\shared_ptr_test.cpp(1) : fatal error C1083: Cannot open include file: 'boost/config.hpp': No such file or directory I can merge it anyway; it shouldn't affect anything besides MSVC 7.1.

Peter Dimov <lists <at> pdimov.com> writes:
Problems with the testing environment (as reported by Ion) aside, I can confirm that the patch solves a problem with Boost.MultiIndex that it's still present in release (where the patch has not been applied): http://tinyurl.com/nvqc9kg So, yes, I'd appreciate if you can merge. Thank you! Joaquín M López Muñoz Telefónica
participants (5)
-
Ion Gaztañaga
-
Joaquin M López Muñoz
-
Joaquín M López Muñoz
-
John Maddock
-
Peter Dimov