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 3 1969
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
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
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<typena me 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>::ty pe_t type_t;};
public:
typedef typename deref_t<T>::typ e_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
---------------------------------------------------------------------------------------- This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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 A {};
class B {};
class C {
stl::vector<B> b;
};
|
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>
|
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:
vector<Neuron<_core_t>*> _neighbors;
|
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++ Design" or similar
books, but I feel there are full of clever guys here
who could help me out.
|
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 not a good ide because
each combination of parameters will the compiler consider as a new type. As
a result of this can the program expand in size.
| |
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
clashing the functions in the two namespaces. Is it a compiler bug? or
intended C++ behavior?
Appreciate if any one can shed some lights for me.
See following:
|
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 that is template
function, then it's argument should be a reference type, such as the
following?
template<class T>
void f(T& t){...}
|
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 some_class {
};
|
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. However I know
that I won't need more than say INT=5. So I do 2 things:
a) have D derive from a base class B (see below)
b) have a class Get with a member B& instance_of_B(unsigned int INT)
(see below). However I can't put references to B into an...
|
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
| |
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |