[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>
::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
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
struct is_const : public true_type{}; template <class T> struct is_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,
All the type_traits tests are marked as passing for VC7.1, other than that I have no idea and no longer have access to that compiler. Sorry I can't be more helpful, John.
On 15/10/2015 13:22, Joaquin M LópezMuñoz wrote:
Hi,
Boost.MultiIndex is failing at master for VC 7.1:
.\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>
::type { };
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
Ion Gaztañaga
On 15/10/2015 13:22, Joaquin M LópezMuñoz wrote:
Boost.MultiIndex is failing at master for VC 7.1:
[...]
template<class Type> struct identity: mpl::if_c< is_const<Type>::value, detail::const_identity_base<Type>, detail::non_const_identity_base<Type>
::type { };
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.
Won't you have direct access to a local MSVC 7.1 installation to play with prior to commiting any changes to github? The if_ thing in particular seems inoffensive enough to try out. Joaquín M López Muñoz Telefónica
On 15/10/2015 20:40, Joaquín M LópezMuñoz wrote:
Won't you have direct access to a local MSVC 7.1 installation to play with prior to commiting any changes to github? The if_ thing in particular seems inoffensive enough to try out.
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
On 15/10/2015 20:40, Joaquín M LópezMuñoz wrote:
Won't you have direct access to a local MSVC 7.1 installation to play with prior to commiting any changes to github? The if_ thing in particular seems inoffensive enough to try out.
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.
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
::value; }
int main()
{
std::cout<
On 16/10/2015 11:14, Joaquin M LópezMuñoz wrote:
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?
[...]
The correct result should be:
0 1 0 1
MSVC-7.1 outputs the same result. During previous experiments I even
checked that is_const
Ion Gaztañaga
[...] During previous experiments I even checked that is_const
::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.
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:
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)?
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
On 17/10/2015 11:00, Joaquín M LópezMuñoz wrote:
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)?
If a dummy "int * = 0" is added to the second overload all tests except serialization related ones pass ok.
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:
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.
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
Ion Gaztañaga
On 18/10/2015 15:15, Joaquín M LópezMuñoz wrote:
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.
It's related to a dependency of Serialization, located in SmartPtr. Peter is already reviewing the pull request:
I see the pull request has been succesfully brought into develop, but not merged to release. Peter? Thank you, Joaquín M López Muñoz Telefónica
Joaquin MLópezMuñoz wrote:
Ion Gaztañaga
writes: On 18/10/2015 15:15, Joaquín M LópezMuñoz wrote:
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.
It's related to a dependency of Serialization, located in SmartPtr. Peter is already reviewing the pull request:
I see the pull request has been succesfully brought into develop, but not merged to release. Peter?
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.
On 27/10/2015 16:37, Peter Dimov wrote:
Joaquin MLópezMuñoz wrote:
Ion Gaztañaga
writes: On 18/10/2015 15:15, Joaquín M LópezMuñoz wrote:
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.
It's related to a dependency of Serialization, located in SmartPtr. Peter is already reviewing the pull request:
I see the pull request has been succesfully brought into develop, but not merged to release. Peter?
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
It seems that my regression runner launched the task twice and removed files while the regression was in execution. I'll try to launch it again. Ion
Peter Dimov
Joaquin MLópezMuñoz wrote:
Ion Gaztañaga
writes: It's related to a dependency of Serialization, located in SmartPtr. Peter is already reviewing the pull request:
I see the pull request has been succesfully brought into develop, but not merged to release. Peter?
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.
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
Joaquin MLópezMuñoz wrote:
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):
So, yes, I'd appreciate if you can merge. Thank you!
Done. You're welcome.
participants (5)
-
Ion Gaztañaga
-
Joaquin M López Muñoz
-
Joaquín M López Muñoz
-
John Maddock
-
Peter Dimov