473,606 Members | 2,825 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

template member functions of a templated class

I have a class which needs to accumulate data. The way we get this data
is by calling a member function which returns float on a number of
different objects of different type (they are all the same type for a
given instance of the class, but different types for different instances.)

#include<set>

using namespace std;

template<class T>
class Data
{
private:
set<float> m_data;
mem_fun_ref_t<f loat, T> m_ftn;
public:
Data() :m_data() {}
}

This is good. Now, I want a function which takes a range of iterators
(which dereference to type T, or in some cases to type T*), and adds all
the data from the iterator range to m_data. It seems like I should be
able to do this with one, or at most two, templated member functions.
How do I deal with having templated member functions inside the
templated class?

template<class T>
class Data
{
---snip
public:
template<class Container>
Add_Data(typena me Container<T>::i terator begin,
typename Container<T>::i terator end);
};

gives me the error: Non-template type Container used as a template.

So I try

--snip
public:
template<class C<T> >
Add_Data(typena me C<T>::iterator begin,
.... end);
--snip

Which gets the error: C is not a template.

I looked up the STL vector constructor which takes a range of iterators,
and it simply uses a construction like:

--snip
public:
template<class _InputIter>
Add_Data(typena me _InputIter begin,
... end);
--snip

However, it seems like then, you could get types which were not in fact
iterators, and even if they were iterators, would dereference to a type
other than T.

Is there a way to restrict what types are acceptable for the template so
that I only get iterators which dereference to T (or T*)?

Also, given that some of the containers I will be taking data from store
T's and some store T*'s, do I need two template functions for these two
possibilities? or just one? or some type of template specialization?
Jul 22 '05 #1
9 2302
Jon Wilson wrote:
I have a class which needs to accumulate data. The way we get this data
is by calling a member function which returns float on a number of
different objects of different type (they are all the same type for a
given instance of the class, but different types for different instances.)

#include<set>

using namespace std;

template<class T>
class Data
{
private:
set<float> m_data;
mem_fun_ref_t<f loat, T> m_ftn;
public:
Data() :m_data() {}
}

This is good. Now, I want a function which takes a range of iterators
(which dereference to type T, or in some cases to type T*), and adds all
the data from the iterator range to m_data. It seems like I should be
able to do this with one, or at most two, templated member functions.
How do I deal with having templated member functions inside the
templated class?

template<class T>
class Data
{
---snip
public:
template<class Container>
Add_Data(typena me Container<T>::i terator begin,
typename Container<T>::i terator end);
};

gives me the error: Non-template type Container used as a template.

So I try

--snip
public:
template<class C<T> >
template<templa te C<class> > ...
Add_Data(typena me C<T>::iterator begin,
I think you're missing the return value type here...
.... end);
--snip

Which gets the error: C is not a template.

I looked up the STL vector constructor which takes a range of iterators,
and it simply uses a construction like:

--snip
public:
template<class _InputIter>
Add_Data(typena me _InputIter begin,
Again, missing the return value type.
... end);
--snip
This way it's actually much better. You will be able to use any type
that complies with the InputIterator requirements.
However, it seems like then, you could get types which were not in fact
iterators, and even if they were iterators, would dereference to a type
other than T.
Of course. But that's the point of templates. Anything that fits should
be able to be used. The requirement is only that _InputIter (BTW, drop
the underscore or lower the case of the first 'i', you're not allowed to
begin a name with "_I", that's reserved) should _only_ satisfy the
following:

operator*() of it should return T

and

operator ++()

should do something that eventually allows you to compare 'begin' and
'end'. See a good book on a better explanation of what InputIterator
should look (or act) like.
Is there a way to restrict what types are acceptable for the template so
that I only get iterators which dereference to T (or T*)?
Yes. By programming the use of specific operators you already restrict
the set of types to those for which those operators are implemented.

Yes, there are other ways to restrict the set of types even further. My
question would be, WHY?
Also, given that some of the containers I will be taking data from store
T's and some store T*'s, do I need two template functions for these two
possibilities? or just one? or some type of template specialization?


You cannot partially specialise a function template, but you can overload
it easily.

Get yourself a decent book on templates and try to begin thinking like its
author (or authors).

V
Jul 22 '05 #2
>
Yes, there are other ways to restrict the set of types even further. My
question would be, WHY?

Possibly for the purpose of overloading? I'm not sure, see below. And
just out of curiousity, what are those ways? Or do I just have to get a
book on templates so I can start thinking like the authors?
Also, given that some of the containers I will be taking data from
store T's and some store T*'s, do I need two template functions for
these two possibilities? or just one? or some type of template
specialization?

You cannot partially specialise a function template, but you can overload
it easily.


In this case, how would I go about overloading it, since the function
signatures would be the same? I thought that you had to have at least
one type (either parameter or return) which was different, and since I'm
using templates, there would be the same number of parameters, and they
would both be of generic type, and the return type (sorry I forgot
those, they should have all been void) is the same. So how can
overloading be done here without adding an extra parameter as a dummy
for the sole purpose of distinguishing the two functions (which seems
rather kludgey to me)?

Get yourself a decent book on templates and try to begin thinking like its
author (or authors).

V


I would very much like to get a good book on templates... do you have
any recommendations ? How about donating the 50+ bucks it'll cost me?...
I'm a PCK (poor college kid) and newsgroups are free.

Since I do not _have_ such a book at this time, and I _do_ have an
immediate problem with templates in my program, I thought I'd ask here,
where there are people who have the money to afford such books. Perhaps
I can begin to think like the people on this and other newsgroups, who
presumably think like the author (or authors) of the books. But I see
that such questions are met with derision... Sorry to have disturbed you.
Jul 22 '05 #3
Jon Wilson wrote:
Yes, there are other ways to restrict the set of types even further. My
question would be, WHY?

Possibly for the purpose of overloading?


I have no idea what that means.
I'm not sure, see below. And
just out of curiousity, what are those ways?
The usual way is to produce some kind of "compile-time assert failure"
using templates. Search for "type lists" or "is_convertible " or ...
Who knows, you might even invent your own way.
Or do I just have to get a
book on templates so I can start thinking like the authors?
It never hurts to get (and hopefully read) good books.
Also, given that some of the containers I will be taking data from
store T's and some store T*'s, do I need two template functions for
these two possibilities? or just one? or some type of template
specialization?


You cannot partially specialise a function template, but you can overload
it easily.

In this case, how would I go about overloading it, since the function
signatures would be the same?


How are they the same? One is based on objects, the other on pointers.
I thought that you had to have at least
one type (either parameter or return) which was different, and since I'm
using templates, there would be the same number of parameters, and they
would both be of generic type, and the return type (sorry I forgot
those, they should have all been void) is the same. So how can
overloading be done here without adding an extra parameter as a dummy
for the sole purpose of distinguishing the two functions (which seems
rather kludgey to me)?
AFAIUI
template<class T> void foo(T);
and
template<class T> void foo(T*);

are overloaded. Now you need to figure out what argument you want to
pass. And you can always specify template arguments directly:

foo<int>(blah
or
foo<int*>(blah

Get yourself a decent book on templates and try to begin thinking like
its
author (or authors).

V

I would very much like to get a good book on templates... do you have
any recommendations ?


"C++ Templates" by Vandevoorde and Josuttis. "Modern C++ Design" by
Alexandrescu.
How about donating the 50+ bucks it'll cost me?...
As soon as I win the lottery.
I'm a PCK (poor college kid) and newsgroups are free.
Libraries are free as well (well, most of them anyway).
Since I do not _have_ such a book at this time, and I _do_ have an
immediate problem with templates in my program, I thought I'd ask here,
where there are people who have the money to afford such books. Perhaps
I can begin to think like the people on this and other newsgroups, who
presumably think like the author (or authors) of the books. But I see
that such questions are met with derision...
Wow... Did they now teach to respond like that in college?
Sorry to have disturbed you.


Aw, quit your whining. Have you even considered looking in the news
archives before asking again?
Jul 22 '05 #4
Jon Wilson wrote:
Since I do not _have_ such a book at this time, and I _do_ have an
immediate problem with templates in my program, I thought I'd ask
here, where there are people who have the money to afford such books.
With a Fermilab address, I'd think you'd find a copy laying around or in the
office library.

You can also go to a Border's or Barnes & Noble, buy a cup of coffee and sit
in the cafe with the book.
Perhaps I can begin to think like the people on this and other
newsgroups, who presumably think like the author (or authors) of the
books. But I see that such questions are met with derision... Sorry
to have disturbed you.


Have you heard the one about looking a gift horse in the mouth?

Jeff
Jul 22 '05 #5
Victor Bazarov wrote:
Jon Wilson wrote:
Yes, there are other ways to restrict the set of types even further. My
question would be, WHY?

Possibly for the purpose of overloading?

I have no idea what that means.


It means that since I was not sure what those methods of restricting
types further are, I could not ignore the possibility that they might
change the function signature, in which case, two different functions
which restrict the types in different ways would have different
signatures, and could be overloaded versions of the same function.
The usual way is to produce some kind of "compile-time assert failure"
using templates. Search for "type lists" or "is_convertible " or ...
Who knows, you might even invent your own way.


Thank you. Given this answer I do not think that these restrictions on
template types change the function signature at all, and thus would have
no effect on overloading.
You cannot partially specialise a function template, but you can
overload
it easily.


In this case, how would I go about overloading it, since the function
signatures would be the same?

How are they the same? One is based on objects, the other on pointers.

AFAIUI
template<class T> void foo(T);
and
template<class T> void foo(T*);

are overloaded. Now you need to figure out what argument you want to
pass. And you can always specify template arguments directly:

foo<int>(blah
or
foo<int*>(blah


If I use the form

template<class T>
class Data
{
--snip
public:
template<class inputIter>
void Add_Data(typena me inputIter, typename inputIter);
};

in which both arguments are generic types, then the function signatures
for a function in which the inputIter dereferences to objects and for a
function in which the inputIter dereferences to pointers are identical.
AFAIK. Is there some reason that this would not be the case? Note,
that I am not using:

template<class T> foo(T t);
and
template<class T> foo(T* p);

which obviously would be overloaded, since the function signatures are
different.

So, I ask again: In this case, how can overloading be done, since the
function signatures are the same? Or am I overlooking some reason why
they might be different?

I would ask your forgiveness for my somewhat irritable previous
response... I was frustrated that I couldn't figure out this problem,
and I perceived your injunction to think like the authors to be a
statement that I was a poor programmer. Which I may well be (although I
like to think not), but nobody likes to be insulted, and given my
already high level of frustration, I kinda lashed out. My apologies.

Regards,
Jon
Jul 22 '05 #6
Jon Wilson wrote:
You cannot partially specialise a function template, but you can
overload
it easily.
In this case, how would I go about overloading it, since the function
signatures would be the same?


How are they the same? One is based on objects, the other on pointers.

AFAIUI
template<class T> void foo(T);
and
template<class T> void foo(T*);

are overloaded. Now you need to figure out what argument you want to
pass. And you can always specify template arguments directly:

foo<int>(blah
or
foo<int*>(blah


If I use the form

template<class T>
class Data
{
--snip
public:
template<class inputIter>
void Add_Data(typena me inputIter, typename inputIter);
};

in which both arguments are generic types, then the function signatures
for a function in which the inputIter dereferences to objects and for a
function in which the inputIter dereferences to pointers are identical.
AFAIK. Is there some reason that this would not be the case? Note,
that I am not using:

template<class T> foo(T t);
and
template<class T> foo(T* p);

which obviously would be overloaded, since the function signatures are
different.

So, I ask again: In this case, how can overloading be done, since the
function signatures are the same? Or am I overlooking some reason why
they might be different?


Well, without knowing what problem you're trying to solve, it's rather
impossible to give a more precise recommendation, but why couldn't you
do something like

template<class T>
class Data
{
--snip
public:
void Add_One_Element (T t);
void Add_One_Element (T* t);
template<class I> void Add_Data(I i1, I i2) {
while (i1 != i2)
Add_One_Element (*i1++);
}
};

Notice, I didn't overload the 'Add_Data' thing, just introduced another
overloaded member function that will be called by template instantiations
of 'Add_Data' depending on the return type of I::operator*().

V
Jul 22 '05 #7
Victor Bazarov wrote:
Jon Wilson wrote:
> You cannot partially specialise a function template, but you can
> overload
> it easily.

In this case, how would I go about overloading it, since the
function signatures would be the same?


How are they the same? One is based on objects, the other on pointers.

AFAIUI
template<class T> void foo(T);
and
template<class T> void foo(T*);

are overloaded. Now you need to figure out what argument you want to
pass. And you can always specify template arguments directly:

foo<int>(blah
or
foo<int*>(blah


If I use the form

template<class T>
class Data
{
--snip
public:
template<class inputIter>
void Add_Data(typena me inputIter, typename inputIter);
};

in which both arguments are generic types, then the function
signatures for a function in which the inputIter dereferences to
objects and for a function in which the inputIter dereferences to
pointers are identical. AFAIK. Is there some reason that this would
not be the case? Note, that I am not using:

template<class T> foo(T t);
and
template<class T> foo(T* p);

which obviously would be overloaded, since the function signatures are
different.

So, I ask again: In this case, how can overloading be done, since the
function signatures are the same? Or am I overlooking some reason why
they might be different?

Well, without knowing what problem you're trying to solve, it's rather
impossible to give a more precise recommendation, but why couldn't you
do something like

template<class T>
class Data
{
--snip
public:
void Add_One_Element (T t);
void Add_One_Element (T* t);
template<class I> void Add_Data(I i1, I i2) {
while (i1 != i2)
Add_One_Element (*i1++);
}
};

Notice, I didn't overload the 'Add_Data' thing, just introduced another
overloaded member function that will be called by template instantiations
of 'Add_Data' depending on the return type of I::operator*().

V


Ahhh... yes, I think that just might work. Thank you for your help!

BTW, just for my future reference, was the description I gave of the
problem I was trying to solve in my original post insufficient? If so,
how can I improve upon it in order to do a better job for future posts?
Of course, this is not a critical issue, so if you're too busy or
anything, don't bother responding. I'm just curious.
Jul 22 '05 #8
Jon Wilson wrote:
[...]
BTW, just for my future reference, was the description I gave of the
problem I was trying to solve in my original post insufficient? If so,
how can I improve upon it in order to do a better job for future posts?
Of course, this is not a critical issue, so if you're too busy or
anything, don't bother responding. I'm just curious.


The original description was fine. But description is not everything.

I remember the old fable: a young man and a girl are in a subway station
necking, paying no attention to the world. An old dude walks by, stops,
and addressing the couple, says, "you are young folk, you think the life
is simple... But the life is so much simpler".

Perhaps I sometimes tend to overemphasize this, but it's often helpful
to just let go of the complicated stuff and become minimalist. Use only
enough effort to get by, you will find that in many situations when C++
is concerned, less is more (regardless of how much I hate that saying).

Templates ("compile-time polymorphism") are (just like the run-time
polymorphism) good when they are not over-complicated by the rest of the
code. You can always make your code very complex and cover all bases and
outfield along with them. Question is, what do you really solve with too
much specifics?...

Ah, don't listen, I'm just rambling like that old dude.

V
Jul 22 '05 #9
Thanks, Victor, you've been very helpful, and I really appreciate it!

Regards,
Jon
Jul 22 '05 #10

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

Similar topics

3
1554
by: Ulrich Heinen | last post by:
Hello, I'm having trouble with a template member function in a non template class. The attached sample program compiles and works just fine with GCC or IBM VisualAge compilers but Sun Workshop 6 (C++ 5.1) doesn't like it. Am I doing something illegal that accidentally works on the two first compilers or is it the Sun compiler that gets it wrong? The sun compiler stumbles over the indicated line with the message "Badly formed expression."
3
1561
by: Andy | last post by:
Someone supposedly knowledgeable tells me that any member function declared in class scope is automatically inlined. I am a little skeptical about this claim. Is this true (I know it cannot be ... I might decide to write a 1000 line function in the class scope). Cheers, Andy
4
2576
by: SainTiss | last post by:
Hi, From what I've read in several places, it seems that explicit specialization of member functions of class templates is allowed, but partial specialization isn't: template<class T, class R> class A { void foo(); }
1
1508
by: Andrew Wilkins | last post by:
Hi, C++ forbids templated virtual member functions. For example, the following will not (should not - it doesn't in GCC 3.4.3) compile: <snip> template <class T> class Example { public:
2
1403
by: gogo1969 | last post by:
Hello, I was wondering why the following code compiles with Intel C++ 8.0 and MS VC++ 7.1 but not with gcc 4.0.1 and Comeau 4.3.3: #include <iostream> template < class T > struct B { template < class O > static O CastTo( T t ) { return O( t ); } };
1
1494
by: Eugene | last post by:
I have just installed VC++2005 Express Ed. and I keep getting a LNK2001 error:unresolved external symbol "public: virtual void __thiscall Circle::draw(void)const " (?draw@Circle@@UBEXXZ) when building the following code: class Coord { private: int x, y; public: Coord (int i1, int i2) : x(i1), y(i2) {}
5
2358
by: =?iso-8859-1?q?Erik_Wikstr=F6m?= | last post by:
The following code works: #include <iostream> template<class T> struct Test { T t; template<class T, template<class U = Tclass V> Test<T>& foo(V<T>& f)
4
1437
by: StephQ | last post by:
I'm still working on the library for the simulation of SDEs. The following test code compiles fine with the digital mars compiler, but fails with gcc. Error: no matching function for call to 'prova(Diff_sine&, double, double)' #include <iostream> #include "math.h"
3
1284
by: riccardo.gherardi | last post by:
Hello. The code below results in a linker error when compiled with Visual Studio 2008, v9.0.21022.8 RTM. The problem disappears when Foo::Bar implementation is moved to the header file. I've read the relevant template FAQs suggesting to never separate definition and declaration of template member functions, but they deal with code that fails to compile. It's a sintax issue (and therefore my fault) or a compiler quirk? Thanks in advance,...
0
8045
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, 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...
0
7981
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,...
0
8467
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, 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...
1
8127
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8320
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6803
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, 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...
0
3952
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2458
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
0
1315
bsmnconsultancy
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...

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.