$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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);
}