Boost logo

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