|
Boost : |
From: Dietmar Kuehl (dietmar_kuehl_at_[hidden])
Date: 2002-05-04 19:44:14
Peter Dimov wrote:
> template<class T> void f(typename ptr<T>::shared p);
>
> ptr<int>::shared q;
>
> f(p); // fail
Well, you can work-around this by not depending on the concrete type
[immediately]. The first approach
template <class SP> void f(SP p);
is, of course, inappropriate because it would be "catch all". A slight
variation (thanks to Howard Hinnant for pointing out this technique in
a different context) removes this "catch all" problem at the cost of
writing a certain default argument:
template <class SP> void f(SP p,
typename is_ptr_shared<SP>::type = 0);
where 'is_ptr_shared' is a template class which has the subtype 'type'
defined if 'typename ptr<typename SP::pointer_type>::shared' is the same
type as 'SP' and otherwise does not have such a type.
Below is a short demo of this idea (needs a reasonable compiler though;
gcc-2.95 failed while EDG and gcc-3.0 compile the code correctly).
-- <mailto:dietmar_kuehl_at_[hidden]> <http://www.dietmar-kuehl.de/> Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/> // --- some smart pointer header --- template <typename T, bool> struct smart_ptr { typedef T pointer_type; }; template <typename T> struct ptr { typedef smart_ptr<T, true> shared; }; template <typename SP, typename Aux = typename ptr<typename SP::pointer_type>::shared> struct is_shared { }; template <typename SP> struct is_shared<SP, SP> { typedef bool type; }; // --- user code --- #include <iostream> template <typename SP> void f(SP p, typename is_shared<SP>::type = true) { std::cout << "shared pointer\n"; } void f(long) { std::cout << "long\n"; } int main() { f(ptr<int>::shared()); f(smart_ptr<int, true>()); // illegal: f(smart_ptr<int, false>()); f(0); }
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk