Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Template class to enable transparent use of pointers or references (http://www.velocityreviews.com/forums/t452558-template-class-to-enable-transparent-use-of-pointers-or-references.html)

a 03-15-2006 06:59 AM

Template class to enable transparent use of pointers or references
 
Hi,

I'm trying to create a helper class that will allow me to use a pointer or
reference to a class without knowing if it is a pointer or reference.

Conceptual example:

//******************
// class B has one public method f
class B
{
public:
void f()
{
}
};

// use a fictional class A to do the following

B b;
B* pb = &b;

A<>( b ).f();
A<>( pb ).f();
//*********************

What this should do is regardless of whether the A constructor receives a
pointer or reference to B, and without having to specify the actual type in
the template argument list, it will be able to call the method f in the same
fashion, using the . operator in this example (or it could be ->)

Here is my attempt at this, using 2 specialized member functions for
reference and pointer types - see my comments below.

//*******************
// helper class A

template< typename T > class A
{
private:
T _t;

public:
A( T t )
: _t( t )
{
}

void f()
{
}
};

// specialized method that works for references to B
template<> inline void A< B& >::f()
{
return _t.f();
}

// specialized method that works for pointers to B
template<> inline void A< B* >::f()
{
return _t->f();
}
//****************

This doesn't work the way I intended. In order for it to work, I have to
specify the argument type in the template argument list, which defeats the
purpose of having this automatically done by the compiler.

A<B&>( b ).f();
A<B*>( pb ).f();

I was expecting that the compiler would be capable of determining the
template argument type from the type of the value passed to the constructor
(b, or pb).

I would appreciate any help or ideas on this.

Thanks,

A



Kai-Uwe Bux 03-15-2006 07:20 AM

Re: Template class to enable transparent use of pointers or references
 
a wrote:

> Hi,
>
> I'm trying to create a helper class that will allow me to use a pointer or
> reference to a class without knowing if it is a pointer or reference.


Sounds like a bad idea. Why do you want to blur distinctions? Usually,
loosing information is nod good.

What is the underlying problem that you are trying to solve?

> Conceptual example:
>
> //******************
> // class B has one public method f
> class B
> {
> public:
> void f()
> {
> }
> };
>
> // use a fictional class A to do the following
>
> B b;
> B* pb = &b;
>
> A<>( b ).f();
> A<>( pb ).f();
> //*********************
>
> What this should do is regardless of whether the A constructor receives a
> pointer or reference to B, and without having to specify the actual type
> in the template argument list, it will be able to call the method f in the
> same fashion, using the . operator in this example (or it could be ->)


Probably, it has to be ->. After all, you cannot overload the dot-operator.
I consider that a defect in the standard, but I abandoned hope that this
will be fixed any time soon.

> Here is my attempt at this, using 2 specialized member functions for
> reference and pointer types - see my comments below.
>
> //*******************
> // helper class A
>
> template< typename T > class A
> {
> private:
> T _t;
>
> public:
> A( T t )
> : _t( t )
> {
> }
>
> void f()
> {
> }
> };
>
> // specialized method that works for references to B
> template<> inline void A< B& >::f()
> {
> return _t.f();
> }
>
> // specialized method that works for pointers to B
> template<> inline void A< B* >::f()
> {
> return _t->f();
> }
> //****************
>
> This doesn't work the way I intended. In order for it to work, I have to
> specify the argument type in the template argument list, which defeats the
> purpose of having this automatically done by the compiler.
>
> A<B&>( b ).f();
> A<B*>( pb ).f();
>
> I was expecting that the compiler would be capable of determining the
> template argument type from the type of the value passed to the
> constructor (b, or pb).
>
> I would appreciate any help or ideas on this.


What about something like:

template < typename T >
class ref_or_ptr {

T * t_ptr;

public:

ref_or_ptr ()
: t_ptr ( 0 )
{}

ref_or_ptr ( T & r )
: t_ptr ( &r )
{}

ref_or_ptr ( T * p )
: t_ptr ( p )
{}

T * operator-> ( void ) {
return ( t_ptr );
}

T & operator* ( void ) {
return ( *t_ptr );
}

T const * operator-> ( void ) const {
return ( t_ptr );
}

T const & operator* ( void ) const {
return ( *t_ptr );
}

}; // ref_or_ptr<>

typedef ref_or_ptr< int > int_whatever;

#include <iostream>

int main ( void ) {
int i = 5;
int_whatever i_alias ( i );
int* i_ptr = new int ( 7 );
int_whatever ptr_alias ( i_ptr );
std::cout << *i_alias << " " << *ptr_alias << '\n';
}


Best

Kai-Uwe Bux




a 03-15-2006 08:06 AM

Re: Template class to enable transparent use of pointers or references
 
Thanks for your reply.

> Sounds like a bad idea. Why do you want to blur distinctions? Usually,
> loosing information is nod good.
>


In general, you are right, it's not the best idea. In my specific case it's
actually quite important to implement this behavior.

I'm building a C++ API that is quite complex but which must address the
needs of a variety of users of all levels, many of whom are not familiar and
get confused by pointers. Since the API must still pass pointers around, I'm
trying to create a set of higher level and easier to use APIs based on
macros and templates. In this specific case, objects of a class B can appear
as reference or pointers, and I want the user to only see them as
references.

Yes, your solution works - thanks!

A



Axter 03-15-2006 08:24 PM

Re: Template class to enable transparent use of pointers or references
 
a wrote:
> Hi,
>
> I'm trying to create a helper class that will allow me to use a pointer or
> reference to a class without knowing if it is a pointer or reference.
>
> Conceptual example:
>
> //******************
> // class B has one public method f
> class B
> {
> public:
> void f()
> {
> }
> };
>
> // use a fictional class A to do the following
>
> B b;
> B* pb = &b;
>
> A<>( b ).f();
> A<>( pb ).f();
> //*********************
>
> What this should do is regardless of whether the A constructor receives a
> pointer or reference to B, and without having to specify the actual type in
> the template argument list, it will be able to call the method f in the same
> fashion, using the . operator in this example (or it could be ->)
>
> Here is my attempt at this, using 2 specialized member functions for
> reference and pointer types - see my comments below.
>
> //*******************
> // helper class A
>
> template< typename T > class A
> {
> private:
> T _t;
>
> public:
> A( T t )
> : _t( t )
> {
> }
>
> void f()
> {
> }
> };
>
> // specialized method that works for references to B
> template<> inline void A< B& >::f()
> {
> return _t.f();
> }
>
> // specialized method that works for pointers to B
> template<> inline void A< B* >::f()
> {
> return _t->f();
> }
> //****************
>
> This doesn't work the way I intended. In order for it to work, I have to
> specify the argument type in the template argument list, which defeats the
> purpose of having this automatically done by the compiler.
>
> A<B&>( b ).f();
> A<B*>( pb ).f();
>
> I was expecting that the compiler would be capable of determining the
> template argument type from the type of the value passed to the constructor
> (b, or pb).
>
> I would appreciate any help or ideas on this.
>

I'm not sure if this is what you're looking for, but check out the
following class:
template<typename T>
class ZeroMemorySafe
{
private:
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;};
public:
typedef typename deref_t<T>::type_t ref_t;
typedef T type_t;
void operator()(ref_t &t)
{
ZeroMemory(&t, sizeof(t));
}
void operator()(ref_t *t)
{
ZeroMemory(t, sizeof(*t));
}
};

I use the above class with the following function:
template<class T>
void ZeroMemoryT(T& t)
{
ZeroMemorySafe<T>()(t);
}

Which allows the above function to work with pointer types, and
reference type.


----------------------------------------------------------------------------------------
David Maisonave
http://axter.com

Top ten member of C++ Expert Exchange:
http://www.experts-exchange.com/Cplusplus
----------------------------------------------------------------------------------------



All times are GMT. The time now is 02:21 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.