Re: C++ code compiles with libstdc++ but not libc++
Re: C++ code compiles with libstdc++ but not libc++
- Subject: Re: C++ code compiles with libstdc++ but not libc++
- From: Jean-Denis MUYS <email@hidden>
- Date: Wed, 03 Oct 2012 15:33:02 +0000
- Thread-topic: C++ code compiles with libstdc++ but not libc++
Thank you Howard, you nailed it. Hats off.
Your "insane" way does work. It has two drawbacks (at least):
- it requires modifying the header of all classes that need the generic rel ops. As you wrote, at this point, we might as well add those 4 operators to the said classes.
- it is incompatible with the legacy libstdc++. At least it doesn't compile straight as given. I don't mind really, but perhaps I could bracket those with conditional compile directives. Which symbol can I test to check what version of the standard library is currently under use?
But the bottom line is that this huge library now compiles with the modern standard C++ library.
Thank you very much for altering libc++ to behave better with code such as this. I am looking forward to an update from the LLVM project…
On 2 oct. 2012, at 19:54, Howard Hinnant <email@hidden>
wrote:
> On Oct 2, 2012, at 12:31 PM, Jean-Denis MUYS <email@hidden> wrote:
>
>>
>> On 2 oct. 2012, at 18:18, Howard Hinnant <email@hidden>
>> wrote:
>>
>>> It is this:
>>>
>>> template< class T >
>>> inline bool
>>> operator!=( const T& x, const T& y )
>>> {
>>> return !( x == y );
>>> }
>>>
>>> that is the trouble maker.
>>>
>>> Howard
>>>
>>
>>
>> Thanks,
>>
>> If I remove it, other parts of the library fail to compile (classes with no ancestors in the STL for example).
>>
>> Besides, I can't see any problem with this template function.
>
> Technically, I think it may even be legal. However this probably isn't the last time it will cause you a problem. It will conflict with several C++11 library components including reverse_iterator, shared_ptr, unique_ptr, and probably more.
>
> That being said, there is a way for me to make __wrap_iterator more attractive for vector<T>::iterator in libc++ and I will do that.
>
>> Is there a way for me to resolve the ambiguity, for example by telling the compiler which implementation it should take in priority?
>
> I can't think of a good/sane workaround for you at the moment, sorry.
>
> Here's a slightly insane way of doing it: Add a trait (e.g. use_generic_relops) that defaults to false:
>
> #include <type_traits>
>
> template <class T>
> struct use_generic_relops
> : public std::false_type
> {
> };
>
> Restrict your generic ops to those types where use_generic_relops<T>::value is true:
>
> template< class T >
> inline
> typename std::enable_if
> <
> use_generic_relops<T>::value,
> bool
>> ::type
> operator!=( const T& x, const T& y )
> {
> return !( x == y );
> }
>
> And then for each type where you want to enable the generic operator, specialize the trait to be true:
>
> class Other
> {
> public:
> friend bool operator==(const Other&, const Other&)
> {return true;}
> };
>
> template <>
> struct use_generic_relops<Other>
> : public std::true_type
> {
> };
>
> I'm not sure that this is easier than just adding the extra 4 operators for Other though.
>
> Historical context:
>
> The standards committee tried this (a generic != operator) just before the C++98 standard. At the last minute they ran into the quagmire you now find yourself in. Instead of yanking the operator, it was put into namespace std::rel_ops with the theory that if someone really wanted to use it, they could "using namespace std::rel_ops;". It was subsequently realized that nobody could actually use it that way without the risk of exposing the ambiguity anyway. Now there's a running joke on the committee whenever we decide we need to get rid of a facility: should we deprecate it or just put it into namespace rel_ops? ;-)
>
> Howard
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden