
Matthias Troyer <troyer@phys.ethz.ch> writes:
On Nov 12, 2006, at 6:46 PM, David Abrahams wrote:
Matthias Troyer <troyer@phys.ethz.ch> 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