
Hi to all, There were some recent Shmem/Interprocess bug reports concerning header ordering issues. I've investigated it a bit and I've come up with a reduced test case that reproduces the problem that happens with the static_pointer_cast() expression. Now that I have reduced the problem, I don't know how to solve it so I need some expert ADL recommendation to implement a "best practices" approach in my boost code. Imagine a container that can store raw pointers or smart pointers pointer to a polymorphic class (or a container using an allocator that defines its own "pointer" type). To avoid instantiations, it uses static_pointer_cast to work only with base classes and avoid code bloat. This is typical in node based containers like lists and trees. Then suppose a container factory that creates containers based on a configuration. Here is the code: //////////////////////////////////////// //containers.hpp header: //////////////////////////////////////// namespace boost { namespace dummy { template<class Pointer> class container { Pointer ptr; public: void func() { static_pointer_cast<int>(Pointer()); } }; } //namespace dummy { } //namespace boost { //////////////////////////////////////// //smart_ptr.hpp header: //////////////////////////////////////// namespace boost { namespace dummy { template<class T> class smart_ptr { }; template<class T, class U> smart_ptr<T> static_pointer_cast(const smart_ptr<U> &u) { return smart_ptr<T>(); } } //namespace dummy { } //namespace boost { //////////////////////////////////////// //container_factory.hpp header: //////////////////////////////////////// namespace boost { namespace dummy { class container_factory { public: template<class Container> static Container *create() { return new Container; } }; } //namespace dummy { } //namespace boost { //////////////////////////////////////// //main.cpp: //////////////////////////////////////// #include "container.h" #include "smart_ptr.h" #include "container_factory.h" int main() { using namespace boost::dummy; typedef container<smart_ptr<int> > my_container; my_container *cont = container_factory::create<my_container>(); cont->func(); return 0; } This code compiles in VC 7.1 and VC 8 but fails with gcc, complaining the "there is no declaration for static_pointer_cast". If we change the header order to: #include "smart_ptr.h" #include "container.h" #include "container_factory.h" This compiles fine because the static_pointer_cast definition is found before the call. My first question is: * Is this gcc error correct? Revising a bit ADL + template issues (a fairly complicated logic that should be removed from C++, in my opinion) I think that gcc is right. * If gcc is correct, what is the implementor supposed to do? Every templatized class header shouldn't include smart_ptr.h because smart_ptr is unknown and it can even be a user-defined class. * If this is correct, that is the user supposed to do? The user has included all the headers, and he shouldn't know about the implementation and internal dependency issues. It's really a mess for a user to start guessing the correct header order. And this is only a simple dependency, imagine a fairly more complicated approach, it would be really a nightmare. So the question is, how should I write my library to take advantage of ADL without creating such header dependency problems? Should I avoid ADL and require static_pointer_cast overloads in boost namespace for a user class defined in a different namespace? I must have missed something, because otherwise, I would find ADL really useless as a robust customization point. Any expert willing to help? Regards, Ion