
I'm trying to use template specialization and enable_if / type_traits to correctly allocate memory for different types, where the template parameter will be one of: 1. boost::intrusive_ptr<U> // create U on the heap, return intrusive_ptr 2. boost::shared_ptr<U> // create U on the heap, return shared_ptr 3. U* // create U on the heap, return raw pointer 4. U // create U on the stack I'm pretty sure I'm just doing something stupid, but I'm getting ambiguous conflicts between my template for types of U and the smart pointer types. Please can you comment on how to fix the code below? TIA Steve #include <boost/utility.hpp> #include <boost/type_traits.hpp> #include <boost/intrusive_ptr.hpp> #include <boost/shared_ptr.hpp> #include <iostream> template<typename U, class Enable = void> struct alloc; template<typename U> struct alloc<U, typename boost::disable_if< boost::is_pointer<U> >::type > { U operator()() { std::cout << __LINE__ << std::endl; return U(); } }; //----------------------------------------------------- template<typename U> struct alloc<U, typename boost::enable_if< boost::is_pointer<U> >::type > { U operator()() { std::cout << __LINE__ << std::endl; return new U; } }; //----------------------------------------------------- template< typename U > struct alloc< boost::intrusive_ptr<U> > { boost::intrusive_ptr<U> operator()() { std::cout << __LINE__ << std::endl; return boost::intrusive_ptr<U>(new U); } }; //----------------------------------------------------- template<typename U > struct alloc< boost::shared_ptr<U> > { boost::shared_ptr<U> operator()() { std::cout << __LINE__ << std::endl; return boost::shared_ptr<U>(new U); } }; //----------------------------------------------------- template<typename T> struct test { alloc<T> create; T fun() { return create(); } }; struct foo { uint32_t refs; foo() : refs() { std::cout << "foo" << std::endl; } }; inline void intrusive_ptr_add_ref(foo* p) { ++p->refs; } inline void intrusive_ptr_release(foo* p) { if (!--p->refs) delete p; } int main() { test<int*> a; int* p = a.fun(); *p = 5; test<int> b; int d = b.fun(); d = 5; test< boost::intrusive_ptr<foo> > c; boost::intrusive_ptr<foo> z = c.fun(); z.get(); test< boost::shared_ptr<int> > gd; boost::shared_ptr<int> x = gd.fun(); x.get(); return 0; }