473,324 Members | 2,548 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,324 software developers and data experts.

Template functions and STL containers

Given a template function:

template <class T>
void foo(T& value)
{
// do something with value
}

Is there any way I can tell whether the type T is an STL container?

For example I'd like, within foo(), to treat "value" differently in
these two cases.
typedef std::vector<bar> barVector;
barVector myBarVector;
foo(myBarVector);

int i13 = 13;
foo(i13);

Normally I'd do a dynamic_cast to determine the type of value, but
because foo() doesn't know the type of the STL container, I can't do it:

template <class T>
void foo(T& value)
{
std::vector<???> test = dynamic_cast<std::vector<???>>(value);
if (test)
{
// It's a vector of ???
}
}

.... but if we're writing generic code, I don't know in advance what
'???' is.

--
Simon Elliott http://www.ctsn.co.uk
Jul 22 '05 #1
8 1281
Simon Elliott wrote:
Given a template function:

template <class T>
void foo(T& value)
{
// do something with value
}

Is there any way I can tell whether the type T is an STL container?
Why do you think you need to?
For example I'd like, within foo(), to treat "value" differently in
these two cases.
typedef std::vector<bar> barVector;
barVector myBarVector;
foo(myBarVector);

int i13 = 13;
foo(i13);
Overload your function templates:

template<class T> void foo(T& v) ..
template<class T> void foo(vector<T>& v) ..

or specialise it/them.
[...]


V
Jul 22 '05 #2
On 07/01/2005, Victor Bazarov wrote:
Given a template function:

template <class T>
void foo(T& value)
{
// do something with value
}

Is there any way I can tell whether the type T is an STL container?


Why do you think you need to?


See below.
For example I'd like, within foo(), to treat "value" differently in
these two cases.
typedef std::vector<bar> barVector;
barVector myBarVector;
foo(myBarVector);

int i13 = 13;
foo(i13);


Overload your function templates:

template<class T> void foo(T& v) ..
template<class T> void foo(vector<T>& v) ..

or specialise it/them.


Nice idea, and it would sort out the issue of trying to get a size from
a generic std::vector when I don't know what type it is containing.
Unfortunately my compiler doesn't like it.

The code looks a lot like this (I haven't run this snippet through the
compiler so there may be the odd typo):

template <class T> int fooCount(const T& value)
{
return(-1);
}

template <class T> int fooCount(const std::vector<T>& value)
{
return(value.size());
}

class fooBase
{
public:
virtual int GetCount()const=0;
};

template <class T> fooDerived
{
private:
T t_;
public:
virtual int GetCount()const
{
return(fooCount(t_));
}
};

Unfortunately when I try to create an instance of fooDerived like this:
typedef std::vector<bar> barVector;
fooDerived<barVector> myFooBar;

I get an error message saying "call to undefined function fooCount".
(Which is odd because you'd have thought it would have picked up the
first, more generic instance.)

I'm trying this on a fairly old compiler (Borland C++ builder 3) so I'm
not sure whether it's a C++ error or a compiler nonconformace. I will
try the above on BCB6 tomorrow.

--
Simon Elliott http://www.ctsn.co.uk
Jul 22 '05 #3
On 07/01/2005, Simon Elliott wrote this, which turned out to be a load
of b*****ks:
Nice idea, and it would sort out the issue of trying to get a size
from a generic std::vector when I don't know what type it is
containing. Unfortunately my compiler doesn't like it.


But it would have done if I hadn't mis-spelled a function name.

Thanks for this: I didn't know you could split up the types on a
function overload.

--
Simon Elliott http://www.ctsn.co.uk
Jul 22 '05 #4
On 07/01/2005, Simon Elliott wrote:
On 07/01/2005, Simon Elliott wrote this, which turned out to be a load
of b*****ks:
Nice idea, and it would sort out the issue of trying to get a size
from a generic std::vector when I don't know what type it is
containing. Unfortunately my compiler doesn't like it.


But it would have done if I hadn't mis-spelled a function name.

Thanks for this: I didn't know you could split up the types on a
function overload.


Hmm. Tracing through the debugger shows that my vector overloaded
function is not being called:

template <class T> int fooCount(const std::vector<T>& value)

Instead, the more general function is being called:

template <class T> int fooCount(const T& value)

Not sure how to ensure that the correct function is being called.

In fact, even if I knew somehow that my type was a vector of some other
contained type, I'm not sure how to proceed given that I don't know
what that contained type is going to be.

--
Simon Elliott http://www.ctsn.co.uk
Jul 22 '05 #5
Simon Elliott wrote:
On 07/01/2005, Simon Elliott wrote:

On 07/01/2005, Simon Elliott wrote this, which turned out to be a load
of b*****ks:

Nice idea, and it would sort out the issue of trying to get a size
from a generic std::vector when I don't know what type it is
containing. Unfortunately my compiler doesn't like it.
But it would have done if I hadn't mis-spelled a function name.

Thanks for this: I didn't know you could split up the types on a
function overload.

Hmm. Tracing through the debugger shows that my vector overloaded
function is not being called:

template <class T> int fooCount(const std::vector<T>& value)

Instead, the more general function is being called:

template <class T> int fooCount(const T& value)

Not sure how to ensure that the correct function is being called.


First of all, make sure that your compiler is not a faulty one. Below
is the code and the output I think it should produce (and it does with
at least one of the compilers I have here).
In fact, even if I knew somehow that my type was a vector of some other
contained type, I'm not sure how to proceed given that I don't know
what that contained type is going to be.


I don't know how you should proceed. You could try overloading your
function based on all _possible_ containers. You could also name those
functions differently (to be used in the derived classes differently).

Honestly, though. Just spend a bit more time tinkering, and you'll get
it, I am sure of it.

----------------------------
#include <iostream>
#include <vector>

template<class T> int getCount(T t)
{
return -1;
}

template<class T> int getCount(std::vector<T> const& vt)
{
return vt.size();
}

struct B
{
virtual int getCount() const = 0;
};

template<class T> struct D1 : B
{
int getCount() const { return ::getCount(db); }
T db;
};

struct D2 : B
{
int getCount() const { return ::getCount(db); }
int db;
};

int main()
{
B *b1 = new D1<std::vector<int> >;
B *b2 = new D2;
std::cout << "D1::getCount returned " << b1->getCount() << std::endl;
std::cout << "D2::getCount returned " << b2->getCount() << std::endl;
return 0;
}
---------------------------- output:
D1::getCount returned 0
D2::getCount returned -1
-----------------------------------------

Victor
Jul 22 '05 #6
On 07/01/2005, Victor Bazarov wrote:
First of all, make sure that your compiler is not a faulty one. Below
is the code and the output I think it should produce (and it does with
at least one of the compilers I have here).
BCB3 and BCB6 won't even compile this. See below. Unfortunately BCB3
and BCB6 are compilers that this code needs to support. I'll see what
gcc makes of this code later today.
I don't know how you should proceed. You could try overloading your
function based on all possible containers. You could also name those
functions differently (to be used in the derived classes differently).
The problem is that the code is intended to be generic. I can easily
make it work if I know in advance the names of the classes the code is
required to accomodate.
Honestly, though. Just spend a bit more time tinkering, and you'll
get it, I am sure of it.
I'll get something that works. But I want something that's simple,
effective, easy to maintain. To achieve this I'll need to learn more
about templates. When I've got a few moments I think I need to have a
look at Andrei Alexandrescu's book.
---------------------------- #include <iostream>
#include <vector>

template<class T> int getCount(T t)
{
return -1;
}

template<class T> int getCount(std::vector<T> const& vt)
{
return vt.size();
}

struct B
{
virtual int getCount() const = 0;
};

template<class T> struct D1 : B
{
int getCount() const { return ::getCount(db); }
BCB3&6 error: Ambiguity between 'getCount(const
std::vector<int,std::allocator<int> >)' and 'getCount(const
std::vector<int,std::allocator<int> > &)'.
T db;
};

struct D2 : B
{
int getCount() const { return ::getCount(db); }
int db;
};

int main()
{
B *b1 = new D1<std::vector<int> >;
B *b2 = new D2;
std::cout << "D1::getCount returned " << b1->getCount() << std::endl;
std::cout << "D2::getCount returned " << b2->getCount() << std::endl;
return 0;
}
---------------------------- output:
D1::getCount returned 0
D2::getCount returned -1
-----------------------------------------

--
Simon Elliott http://www.ctsn.co.uk
Jul 22 '05 #7
On 08/01/2005, Simon Elliott wrote:
I'll get something that works. But I want something that's simple,
effective, easy to maintain. To achieve this I'll need to learn more
about templates. When I've got a few moments I think I need to have a
look at Andrei Alexandrescu's book.


I didn't need to go that far: another RTFM of the std::vector docs
revealed a helpful feature: std::vector defines a typedef value_type
which you can use in templates to represent the type contained by the
vector.

--
Simon Elliott http://www.ctsn.co.uk
Jul 22 '05 #8
"Simon Elliott" <Simon at ctsn.co.uk> wrote...
On 08/01/2005, Simon Elliott wrote:
I'll get something that works. But I want something that's simple,
effective, easy to maintain. To achieve this I'll need to learn more
about templates. When I've got a few moments I think I need to have a
look at Andrei Alexandrescu's book.


I didn't need to go that far: another RTFM of the std::vector docs
revealed a helpful feature: std::vector defines a typedef value_type
which you can use in templates to represent the type contained by the
vector.


I am sure you've seen this, but in case you haven't, every container in
the Standard library defines that type. So, you can even be relatively
container-independent...

Good luck! You're on the right track.

V
Jul 22 '05 #9

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

Similar topics

2
by: Christophe Barbe | last post by:
I posted a few days ago about the same problem but was not very clear. So here is my second take at it. Basically with GCC 3.3.2, I can't compile the example from the C++ FAQ Lite available...
17
by: Jacek Dziedzic | last post by:
Hello! I have a templated class that serves as a simple vector of elements. template <typename T> class simple_vector : public math_object { // ... lots of simple_vector operations // the...
5
by: nifsmith | last post by:
Hi I am trying to learn about Queues and use templates at the same time. I have written the following code and I am getting a link error, stating "unresolved external symbol, "int__cdecl...
7
by: Lieven | last post by:
I want to make a function template that is generic over all of the stl-containers. This function can take a vector, a set or stack as input and as second argument the class of the contents of the...
9
by: Jon Wilson | last post by:
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...
4
by: Mark P | last post by:
I'm trying to define a templatized version of operator<< to print out information about a template class. The code below won't compile. (error: no match for std::ostream& << Outer<int>::Inner&) ...
4
by: pocmatos | last post by:
Hi all, I have an abstract class acting as interface to a given class of objects. And mostly everywhere around my program I'm passing things like: vector<int>, list<unsigned long>,...
1
by: Nishith Prabhakar | last post by:
Hi, I have a class which inherits from a template (vector). This class is defined in the header file as below. Output.h class _DLL_RESPONSE_SERVER Output : public vector<SingleOutput> {...
9
by: rtalbot | last post by:
I've got a container that looks like this: template <class T> class Foo { public: Foo() : _data(), _status(1) { } Foo(T) : _data(T), _status(0) { } ~Foo() { }
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.