|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2006-11-13 10:08:31
Matthias Troyer <troyer_at_[hidden]> writes:
> On Nov 12, 2006, at 6:46 PM, David Abrahams wrote:
>
>> Matthias Troyer <troyer_at_[hidden]> writes:
>>
>>> Hi Beman, hi all
>>>
>>> Due to recent changes to the filesystem library now, the header
>>> detail/identifier.hpp is now included in my projects and contains the
>>> dangerous code segment:
>>
>> Is it just dangerous by definition, because it breaks
>> your code on your compiler, or is there something else about it that
>> I'm missing?
>
> I feel that any
>
> template <class A, class B>
> ... operator<<(A&, B const&>
>
> is quite dangerous.
Well, okay, we can talk about that, but that's completely irrelevant
to a clash with your own Id I think.
> The enable_if is meant to make it safe, but
> somehow SFINAE is not working here.
>>
>>> template <class Ostream, class Id>
>>> typename enable_if< is_base_of< identifier< typename
>>> Id::value_type, Id >, Id >,
>>> Ostream & >::type operator<<( Ostream & os, const Id & id )
>>> {
>>> return os << id.value();
>>> }
>>>
>>> which breaks all of my codes, since I have a type Id, that has a type
>>> member Id::value_type which is an abstract base class. My compiler
>>> (Apple gcc-4.0) now tries to instantiate identifier< typename
>>> Id::value_type, Id >, which fails because Id::value_type is abstract,
>>> and the compiler aborts with an error message.
>>
>> Is that a compiler bug?
>
> I'm not sure, it could be:
>
> identifier< typename Id::value_type, Id >
>
> fails to get instantiated because typename Id::value_type is an
> abstract type. Should SFINAE catch this without giving an error?
No.
>> Is your Id in namespace boost?
>
> Yes, it is a shared_ptr<T> where T is an abstract base class.
That doesn't answer my question. I thought you said you had your own
type, "Id," that was getting picked up and used instead of the
template parameter? I'm asking whether that's defined in your own
namespace or in namespace boost.
Maybe you're actually saying that you don't have a type called Id; you
just have
shared_ptr<T>.
Fair enough. I think the correct thing to do is put the definition of
class template identifier in its own subnamespace of boost along with
the streaming operator (no need for enable_if). It could then be
imported into namespace boost with a using declaration...
Frankly, I'm not sure that reserving the name boost::identifier is the
right thing to do, especially if it's in a detail header. Is this a
public interface, or not? If not, it shouldn't be directly in
boost::. If so, it should be documented somewhere and it should have
passed through a review. Did it?
-- Dave Abrahams Boost Consulting www.boost-consulting.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk