473,425 Members | 2,002 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,425 software developers and data experts.

Template class to enable transparent use of pointers or references

a
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
Mar 15 '06 #1
3 1948
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

Mar 15 '06 #2
a
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
Mar 15 '06 #3
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
----------------------------------------------------------------------------------------

Mar 15 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: Michael Winter | last post by:
Is the Standard Template Library capable of storing complete objects rather than pointers. For example, would either of the vectors below (a, c) function correctly (note the member in C). class...
13
by: Imre | last post by:
Please take a look at the following code: template <typename T, typename Enable = void> class A { public: enum { value = 0 }; }; template <typename T>
3
by: andreykuzmenko | last post by:
I am trying to create a template class, which would store a vector of references to objects of the same class. Like: template<class _core_t> class Neuron { ///snipped private:...
5
by: Pelle Beckman | last post by:
Hi, I've done some progress in writing a rather simple singleton template. However, I need a smart way to pass constructor arguments via the template. I've been suggested reading "Modern C++...
3
by: Tony Johansson | last post by:
Hello experts! Is there any limitation for template parameter that normal function parameters doesn't have? What does this text below mean. To use template parameters as constans is normally...
16
by: xman | last post by:
I defined namespace hpc in main.cpp, so not to clash with other libraries. But I found that, in namespace boo, instantiating a template with a class in namespace hpc, causes compilation errors by...
7
by: Jess | last post by:
Hello, I learned that when I work with templates in C++, I should have functions that pass arguments by reference because the type of object is not known. Does it mean that if I have a function...
3
by: Thomas Pajor | last post by:
Hey everybody, I got into serious trouble with template programming. I have a class which uses three template arguments, say template<typename Atype, typename Btype, typename Ctype> class...
1
by: er | last post by:
Hi All, I have a class D<INTwhich serves a small implementation purpose (think for example D<INTis Factorial<INT>). I don't want every class that uses D<INTto depend on template parameter INT....
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.