ptr_policy class template type

A

Axter

I'm fine tuning a scope_handle class that takes a policy class as the
second template.
http://code.axter.com/scope_handle.h
Please see above link for full understanding of the problem.

One thing I don't like about the way the current policy template is
setup is that for the ptr_policy class the first template type is
different from the template type given to the policy.
And on the other policy classes, the template type is the same. (Which
is what I prefer)
Example:
scope_handle<char*, implicit_conversion_policy<char*> >
scope_handle<FILE, implicit_conversion_policy<FILE> >
scope_handle<HANDLE, no_policy<HANDLE> >

and for ptr_policy

scope_handle<Mynode*, ptr_policy<Mynode> >

I would like to be able to setup the ptr_policy class so that it takes
the same type as the first template type.

scope_handle<Mynode*, ptr_policy<Mynode*> >

But then if I do that, I can't seem to figure out a way to get the
dereference type declaration on the T& operator*() function.

template<typename T>
class ptr_policy
{
protected:
typedef typename T* type_t;
ptr_policy(type_t type):m_handle(type){}
type_t m_handle;
public:
type_t operator->() const{return m_handle;}
T& operator*() const{return *m_handle;}
bool operator! () const{return m_handle == 0;}
};

If T is of type (foo*) instead of (foo), is there any way to get type
(foo&) out of type (foo*)?

FYI: ******* I'm not asking about dereferencing the variable. I'm
referring to how to dereference the TYPE *******
 
J

Jack Saalweachter

Axter said:
I'm fine tuning a scope_handle class that takes a policy class as the
second template.
http://code.axter.com/scope_handle.h
Please see above link for full understanding of the problem.

One thing I don't like about the way the current policy template is
setup is that for the ptr_policy class the first template type is
different from the template type given to the policy.
And on the other policy classes, the template type is the same. (Which
is what I prefer)
Example:
scope_handle<char*, implicit_conversion_policy<char*> >
scope_handle<FILE, implicit_conversion_policy<FILE> >
scope_handle<HANDLE, no_policy<HANDLE> >

and for ptr_policy

scope_handle<Mynode*, ptr_policy<Mynode> >

I would like to be able to setup the ptr_policy class so that it takes
the same type as the first template type.

scope_handle<Mynode*, ptr_policy<Mynode*> >

But then if I do that, I can't seem to figure out a way to get the
dereference type declaration on the T& operator*() function.

template<typename T>
class ptr_policy
{
protected:
typedef typename T* type_t;
ptr_policy(type_t type):m_handle(type){}
type_t m_handle;
public:
type_t operator->() const{return m_handle;}
T& operator*() const{return *m_handle;}
bool operator! () const{return m_handle == 0;}
};

If T is of type (foo*) instead of (foo), is there any way to get type
(foo&) out of type (foo*)?

FYI: ******* I'm not asking about dereferencing the variable. I'm
referring to how to dereference the TYPE *******
OK, I'm interpreting this to mean that you'll have some "template
<typename T>", and you want to be able to dereference that, whether it's
an int, an int*, or an int*****. If not, everything I am about to say
is completely worthless.

The way in which I would do this is as follows:
template <typename T>
struct deref_t {
typedef T type_t;
typedef type_t& ref_t;

static ref_t deref(ref_t t) { return t; }
};

template <typename T>
struct deref_t<T*> {
typedef typename deref_t<T>::type_t type_t;
typedef type_t& ref_t;

static ref_t deref(T *t) { return deref_t<T>::deref(*t); }
};

template <typename T>
typename deref_t<T>::ref_t deref(T &t) {
return deref_t<T>::deref(t);
}


So, what happens goes something like this. We call the function
"deref(p)". The template wrapping that function detects our type, fills
in the appropriate return type [this is important; the trickiest part of
this is getting the return type right], and calls the function inside of
our specialized wrapper class.

Our wrapper class does straight forward recursion with templates. If p
is a pointer, it calls itself on *p. If p is not a pointer, it returns.
 
A

Axter

Jack said:
Axter said:
I'm fine tuning a scope_handle class that takes a policy class as the
second template.
http://code.axter.com/scope_handle.h
Please see above link for full understanding of the problem.

One thing I don't like about the way the current policy template is
setup is that for the ptr_policy class the first template type is
different from the template type given to the policy.
And on the other policy classes, the template type is the same. (Which
is what I prefer)
Example:
scope_handle<char*, implicit_conversion_policy<char*> >
scope_handle<FILE, implicit_conversion_policy<FILE> >
scope_handle<HANDLE, no_policy<HANDLE> >

and for ptr_policy

scope_handle<Mynode*, ptr_policy<Mynode> >

I would like to be able to setup the ptr_policy class so that it takes
the same type as the first template type.

scope_handle<Mynode*, ptr_policy<Mynode*> >

But then if I do that, I can't seem to figure out a way to get the
dereference type declaration on the T& operator*() function.

template<typename T>
class ptr_policy
{
protected:
typedef typename T* type_t;
ptr_policy(type_t type):m_handle(type){}
type_t m_handle;
public:
type_t operator->() const{return m_handle;}
T& operator*() const{return *m_handle;}
bool operator! () const{return m_handle == 0;}
};

If T is of type (foo*) instead of (foo), is there any way to get type
(foo&) out of type (foo*)?

FYI: ******* I'm not asking about dereferencing the variable. I'm
referring to how to dereference the TYPE *******
OK, I'm interpreting this to mean that you'll have some "template
<typename T>", and you want to be able to dereference that, whether it's
an int, an int*, or an int*****. If not, everything I am about to say
is completely worthless.

The way in which I would do this is as follows:
template <typename T>
struct deref_t {
typedef T type_t;
typedef type_t& ref_t;

static ref_t deref(ref_t t) { return t; }
};

template <typename T>
struct deref_t<T*> {
typedef typename deref_t<T>::type_t type_t;
typedef type_t& ref_t;

static ref_t deref(T *t) { return deref_t<T>::deref(*t); }
};

template <typename T>
typename deref_t<T>::ref_t deref(T &t) {
return deref_t<T>::deref(t);
}


So, what happens goes something like this. We call the function
"deref(p)". The template wrapping that function detects our type, fills
in the appropriate return type [this is important; the trickiest part of
this is getting the return type right], and calls the function inside of
our specialized wrapper class.

Our wrapper class does straight forward recursion with templates. If p
is a pointer, it calls itself on *p. If p is not a pointer, it returns.

Thanks for trying to answer my question, but that's not exactly what
I'm looking for.
I need to be able to get type (int) when the template type is (int*).
Or type (int&) when the template type is (int*).

I can get type (int*) or type (int&) when the template type is (int).
But I want to be able to do it the other way around.
 
S

Shezan Baig

Axter said:
Thanks for trying to answer my question, but that's not exactly what
I'm looking for.
I need to be able to get type (int) when the template type is (int*).
Or type (int&) when the template type is (int*).

I can get type (int*) or type (int&) when the template type is (int).
But I want to be able to do it the other way around.



Jack's solution already does this. E.g.:

typedef deref_t<int*>::type_t Int;

Int i = 0; // equivalent to "int i = 0;"


Hope this helps,
-shez-
 
M

mlimber

Axter said:
Jack said:
Axter said:
I'm fine tuning a scope_handle class that takes a policy class as the
second template.
http://code.axter.com/scope_handle.h
Please see above link for full understanding of the problem.

One thing I don't like about the way the current policy template is
setup is that for the ptr_policy class the first template type is
different from the template type given to the policy.
And on the other policy classes, the template type is the same. (Which
is what I prefer)
Example:
scope_handle<char*, implicit_conversion_policy<char*> >
scope_handle<FILE, implicit_conversion_policy<FILE> >
scope_handle<HANDLE, no_policy<HANDLE> >

and for ptr_policy

scope_handle<Mynode*, ptr_policy<Mynode> >

I would like to be able to setup the ptr_policy class so that it takes
the same type as the first template type.

scope_handle<Mynode*, ptr_policy<Mynode*> >

But then if I do that, I can't seem to figure out a way to get the
dereference type declaration on the T& operator*() function.

template<typename T>
class ptr_policy
{
protected:
typedef typename T* type_t;
ptr_policy(type_t type):m_handle(type){}
type_t m_handle;
public:
type_t operator->() const{return m_handle;}
T& operator*() const{return *m_handle;}
bool operator! () const{return m_handle == 0;}
};

If T is of type (foo*) instead of (foo), is there any way to get type
(foo&) out of type (foo*)?

FYI: ******* I'm not asking about dereferencing the variable. I'm
referring to how to dereference the TYPE *******
OK, I'm interpreting this to mean that you'll have some "template
<typename T>", and you want to be able to dereference that, whether it's
an int, an int*, or an int*****. If not, everything I am about to say
is completely worthless.

The way in which I would do this is as follows:
template <typename T>
struct deref_t {
typedef T type_t;
typedef type_t& ref_t;

static ref_t deref(ref_t t) { return t; }
};

template <typename T>
struct deref_t<T*> {
typedef typename deref_t<T>::type_t type_t;
typedef type_t& ref_t;

static ref_t deref(T *t) { return deref_t<T>::deref(*t); }
};

template <typename T>
typename deref_t<T>::ref_t deref(T &t) {
return deref_t<T>::deref(t);
}


So, what happens goes something like this. We call the function
"deref(p)". The template wrapping that function detects our type, fills
in the appropriate return type [this is important; the trickiest part of
this is getting the return type right], and calls the function inside of
our specialized wrapper class.

Our wrapper class does straight forward recursion with templates. If p
is a pointer, it calls itself on *p. If p is not a pointer, it returns.

Thanks for trying to answer my question, but that's not exactly what
I'm looking for.
I need to be able to get type (int) when the template type is (int*).
Or type (int&) when the template type is (int*).

I can get type (int*) or type (int&) when the template type is (int).
But I want to be able to do it the other way around.

I also think Jack's post gives you what you want. Compare also the type
trait facilities in Boost.Typetraits
(http://boost.org/doc/html/boost_typetraits.html, esp. remove_pointer
and the like) and in Loki (http://sourceforge.net/projects/loki-lib/).

Cheers! --M
 
A

Axter

Jack said:
Axter said:
I'm fine tuning a scope_handle class that takes a policy class as the
second template.
http://code.axter.com/scope_handle.h
Please see above link for full understanding of the problem.

One thing I don't like about the way the current policy template is
setup is that for the ptr_policy class the first template type is
different from the template type given to the policy.
And on the other policy classes, the template type is the same. (Which
is what I prefer)
Example:
scope_handle<char*, implicit_conversion_policy<char*> >
scope_handle<FILE, implicit_conversion_policy<FILE> >
scope_handle<HANDLE, no_policy<HANDLE> >

and for ptr_policy

scope_handle<Mynode*, ptr_policy<Mynode> >

I would like to be able to setup the ptr_policy class so that it takes
the same type as the first template type.

scope_handle<Mynode*, ptr_policy<Mynode*> >

But then if I do that, I can't seem to figure out a way to get the
dereference type declaration on the T& operator*() function.

template<typename T>
class ptr_policy
{
protected:
typedef typename T* type_t;
ptr_policy(type_t type):m_handle(type){}
type_t m_handle;
public:
type_t operator->() const{return m_handle;}
T& operator*() const{return *m_handle;}
bool operator! () const{return m_handle == 0;}
};

If T is of type (foo*) instead of (foo), is there any way to get type
(foo&) out of type (foo*)?

FYI: ******* I'm not asking about dereferencing the variable. I'm
referring to how to dereference the TYPE *******
OK, I'm interpreting this to mean that you'll have some "template
<typename T>", and you want to be able to dereference that, whether it's
an int, an int*, or an int*****. If not, everything I am about to say
is completely worthless.

The way in which I would do this is as follows:
template <typename T>
struct deref_t {
typedef T type_t;
typedef type_t& ref_t;

static ref_t deref(ref_t t) { return t; }
};

template <typename T>
struct deref_t<T*> {
typedef typename deref_t<T>::type_t type_t;
typedef type_t& ref_t;

static ref_t deref(T *t) { return deref_t<T>::deref(*t); }
};

template <typename T>
typename deref_t<T>::ref_t deref(T &t) {
return deref_t<T>::deref(t);
}


So, what happens goes something like this. We call the function
"deref(p)". The template wrapping that function detects our type, fills
in the appropriate return type [this is important; the trickiest part of
this is getting the return type right], and calls the function inside of
our specialized wrapper class.

Our wrapper class does straight forward recursion with templates. If p
is a pointer, it calls itself on *p. If p is not a pointer, it returns.

Sorry for my previous post, but I now see that your proposed method is
what I'm looking for.
I really didn't understand it, and to be honest, I still don't fully
understand what is making that work.
Here's the modify class using the method you posted:
template<typename T>
class ptr_policy
{
protected:
template <typename TT> struct deref_t {typedef TT type_t;};
template <typename TT> struct deref_t<TT*> {typedef typename
deref_t<TT>::type_t type_t;};
typedef typename deref_t<T>::type_t ref_t;
typedef typename T type_t;
ptr_policy(type_t type):m_handle(type){}
type_t m_handle;
public:
type_t operator->() const{return m_handle;}
ref_t& operator*() const{return *m_handle;}
bool operator! () const{return m_handle == 0;}
};

Thank you very much!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,146
Messages
2,570,832
Members
47,374
Latest member
EmeliaBryc

Latest Threads

Top