By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,264 Members | 1,761 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,264 IT Pros & Developers. It's quick & easy.

Template spezialization

P: n/a
Hi,
I would like to write a template class Polygon<VertexTypthere vertex
typ can be eigther a pointer or a value typ.

It has an attribute:
std::vector<VertexTypvertices;

And a methode:
VertexValueTyp& vertex(int i);
that dereferences vertices[i] internally in case VertexTyp is a pointer
type.

How can I achieve this? Are there any step-by-step guides online?

Thanks in advance,
Thomas Kowalski

Sep 24 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Thomas Kowalski <th***@gmx.dewrote:
I would like to write a template class Polygon<VertexTypthere vertex
typ can be eigther a pointer or a value typ.

It has an attribute:
std::vector<VertexTypvertices;

And a methode:
VertexValueTyp& vertex(int i);
that dereferences vertices[i] internally in case VertexTyp is a
pointer type.

How can I achieve this? Are there any step-by-step guides online?
The following template and its specialization should give you an
idea:

template <typename T>
class A
{

};

template <typename S>
class A <S*>
{
};

int main ()
{
A <charaa;
A <char*ab;
}

You would have to completely reimplement the specialization of the
template class.

There are also ways to move the specialization out of the main class
by using inheritance:

template <typename T>
class special_A
{
// stuff for non-pointers
};

template <typename S>
class special_A <S*>
{

// stuff for pointers
};

template <typename T>
class A : special_A <T>
{
// common functions etc which will be merged
// with the special things
};

int main ()
{
A <charaa;
A <char*ab;
}

Now you can provide different implementations in the 'special_A'
template and its specialization and the common stuff in the template
class 'A'. One problem you will face is the ability to cast 'A <char>'
to 'special_A <char>' if you use public inheritance (so your special
functions are exposed). But if you use private inheritance, your special
functions are not available to the user of 'A <char>'. One solution
could be to create a typedef inside the special_A template and its
specialization, which determine the return type of the common function
and use private inheritance:

#include <cstddef>

template <typename T>
class special_A
{
protected:
typedef T ret_t;

ret_t impl ();
};

template <typename S>
class special_A <S*>
{
protected:
typedef S ret_t;

ret_t impl ();
};

template <typename T>
class A : special_A <T>
{
public:
typename special_A <T>::ret_t get_element (std::size_t idx) { return
special_A <T>::impl (); }
};

int main ()
{
A <charaa;
A <char*ab;

char ret_aa = aa.get_element (0);
char ret_ab = ab.get_element (0);
}

Now you cannot legally cast the 'A <char>' objects to 'special_A
<char>' and you can still reuse common functions of your class without
having to rewrite them for the specialization.

hth
--
jb

(reply address in rot13, unscramble first)
Sep 24 '06 #2

P: n/a

Thomas Kowalski wrote:
Hi,
I would like to write a template class Polygon<VertexTypthere vertex
typ can be eigther a pointer or a value typ.

It has an attribute:
std::vector<VertexTypvertices;

And a methode:
VertexValueTyp& vertex(int i);
that dereferences vertices[i] internally in case VertexTyp is a pointer
type.

How can I achieve this? Are there any step-by-step guides online?

Thanks in advance,
Thomas Kowalski
You have not given any details about VertexTyp. We don't know if you
are dealing with a template parameter that has member functions or is
it just a POD. I'm going to assume a POD for now.

As far as the method is concerned, its actually an operator that you
will prefer dealing with ( operator[] ). Basicly, since Polygon is just
a container wrapping a std::vector, why not match the interface that
std::vector already provides?

Here is an example that uses the name Container instead of Polygon and
a simple int instead of VertexTyp. Lets face it, if you can't get a
templated container handling primitive integers and their pointers
working, how will u be able to get to work with a more complex type?

#include <iostream>
#include <ostream>
#include <vector>

template < typename T >
class Container
{
std::vector< T v;
public:
Container() : v() { }
Container(size_t sz) : v(sz) { }
~Container() { }
/* member functions */
size_t size() const { return v.size(); }
void push_back( const T& r_t ) { v.push_back(r_t); }
T& operator[]( const unsigned index ) { return v.at(index); }
};

int main()
{
const unsigned sz( 5 );
Container< int integers(sz); // a vector of 5 integers
Container< int* pointers; // an empty vector of pointers to int

for ( size_t i = 0; i < integers.size(); ++i )
{
integers[i] = static_cast<int>(i);
pointers.push_back( &integers[ i ] );
}

// test
*pointers[0] = 101;

for ( size_t i = 0; i < integers.size(); ++i )
{
std::cout << pointers[i] << "\t";
std::cout << integers[i] << std::endl;
}
return 0;
}

/*
0x503010 101
0x503014 1
0x503018 2
0x50301c 3
0x503020 4
*/

Remember that your VertexTyp needs to support copy semantics.

Sep 24 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.