Article View: comp.std.c++
Article #1688Global conversion function names / type casts (templates!) ...
From: ctv
Date: Wed, 09 Aug 1995 12:25
Date: Wed, 09 Aug 1995 12:25
148 lines
4017 bytes
4017 bytes
Operator overloading can be used to implement so called smart
pointers. Operator "=", "->", etcetera member functions allow
these smart pointers to be used in (almost) the same way as real
pointers.
How to mimic real-pointer-like casts when the pointers are actually
smart pointers ?
Given the smart pointer template class as sketched in the second
code fragment below, I would like to have a conversion (template)
function as depicted in the first code fragment.
To what extent does this first fragment violate the current C++
definition:
1) Is it allowed to have global (i.e. non-class member) cast
functions (operator ConversionFunctionName() ) ?
2) Usually (?) different instantiations of the same template
function are based on differences in their parameters: what
I would like to have is that class names as well as template
class names can be used to define a generic (and user verified)
conversion function framework like it is sketched below in:
"template<class To, class From>" What motivation makes it
unreasonable to expect that not only the parameters can be
"parameterized" but also the function name because it is a
user defined (template) class name ?
3) In which ways does this sketch violate the current C++ definition ?
(at least, the 5 different C++ compilers I use don't accept
(several slightly different implementations of) this example).
Suggestions for an elegant solution ? Of course, it's possible
to define an explicit template function with a name that's not
based on a template class name, however that's not the sort of
solution I'm looking for ....
Example:
class c1; class c2;
ptr<c1> p1; ptr<c2> p2; // smart pointers p1, p2 to
// instances of c1, c2
// See code fragment 1 for:
p2 = ptr<c2> (p1); // function notation
// or:
p2 = (ptr<c2>) p1; // cast notation
Thanks for your help,
-- Cees Visser
========= ========= ========= ========= ========= =========
Code fragment 1:
========= ========= ========= ========= ========= =========
template<class To, class From> ::operator ptr<To> (ptr<From>& from)
{
ptr<To> to;
// run-time checks ...
to.ptr_ = (To *) from.ptr_ ;
return to;
}
========= ========= ========= ========= ========= =========
Code fragment 2:
========= ========= ========= ========= ========= =========
template<class T> class ptr {
private:
T *ptr_; /* real object pointer */
void incr_refc (T* tp) {
// ...
}
void decr_refc (T* tp) {
// ...
}
public:
ptr (void) {
ptr_ = 0;
}
ptr (const ptr& obj) {
ptr_ = obj.ptr_;
incr_refc (ptr_);
}
ptr (T *t) {
ptr_ = t;
incr_refc (ptr_);
}
~ptr (void) {
// ...
}
/* ptr assignment: */
void operator = (ptr& obj) {
decr_refc (ptr_);
ptr_ = obj.ptr_;
incr_refc (ptr_);
return /* not *this */ ;
}
/* null ptr assignment: */
void operator = (void *null_ptr) {
decr_refc (ptr_);
verify (null_ptr == NULL);
ptr_ = 0;
return /* not *this */ ;
}
T* operator -> () {
verify (ptr_ != 0);
return ptr_;
}
/* dereference */
T& operator * () {
verify (ptr_ != 0);
return *ptr_ ;
}
int operator == (ptr& obj) {
return ptr_ == obj.ptr_;
}
int operator != (ptr& obj) {
return ptr_ != obj.ptr_;
}
friend template<class T, class F> ::operator ptr<T>(ptr<F> f);
};
Technical Details
Message-ID:
<DD1MI7.C8H.0.-s@cs.vu.nl>Path:
arc1-ca.pugleaf.net!cs.vu.nl!ctvShow Full Headers
Complete Article Headers
Newsgroups: comp.std.c++ Path: arc1-ca.pugleaf.net!cs.vu.nl!ctv From: ctv@cs.vu.nl (ctv) Subject: Global conversion function names / type casts (templates!) ... Nntp-Posting-Host: contest.cs.vu.nl Sender: news@cs.vu.nl Organization: VU, Amsterdam Date: Wed, 9 Aug 1995 12:25:19 GMT X-Newsreader: TIN [version 1.2 PL2] Message-ID: <DD1MI7.C8H.0.-s@cs.vu.nl>