473,324 Members | 2,473 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 trick?

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 trouble begins here:

T sum() {
// calculates and returns a sum of all elements of the vector
}
};

The trouble begins whenever I try to have a vector that would
hold elements of, say, double[6]. Trying to instantiate that
gives an error, because the return type of sum() becomes an
array, which is impossible.

Is there a simple way to let the user have instances of
simple_vector<int> for which the sum() operation makes sense
while also allowing simple_vector<double[6]> to be instantiated
and only break upon trying to sum() these?

I was hoping that specialization would fix this, but whenever
I try to move the sum() function out of the template declaration
and make it a

template<> simple_vector<int>::sum() {
}

the compiler complains that the template does not contain a
function called sum(). But of course leaving a declaration of
sum as T sum() within the template declaration will lead to
the same error that sum() can't return an array.

I've googled c.l.c++ only to begin to suspect that I need function
specialization and not template specialization and that it cannot
be done. Is it so?

NB: this is only a stripped-down example. Suggestions to use
a std::vector<double> instead of double[6] or to create a double6
struct won't fix my problem.

So in general: what I need is a template, a few functions of
which need to look differently for different T's, where T is the
template typename parameter. Or better -- can I make some
template member function hidden for certain T's, for which
these functions don't make sense/become illegal?

thanks in advance,
- J.
Jul 22 '05 #1
17 2002
On Tue, 04 May 2004 17:24:05 +0200, Jacek Dziedzic
<jacek__NOSPAM__@janowo_NO_spam_.net> wrote:
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 trouble begins here:

T sum() {
// calculates and returns a sum of all elements of the vector
}
};

The trouble begins whenever I try to have a vector that would
hold elements of, say, double[6]. Trying to instantiate that
gives an error, because the return type of sum() becomes an
array, which is impossible.
I think you're SOL with respect to elements of type double[6], because
they're not assignable or copyable. You can't put things into containers
that aren't assignable/copyable. I feel like an idiot, because I've spent
an hour or more playing with this, until I finally got an error that made
me realize there's no way it can ever work.

Perhaps you can make do with storing vectors instead of the arrays of 6
doubles?
-leor


Is there a simple way to let the user have instances of
simple_vector<int> for which the sum() operation makes sense
while also allowing simple_vector<double[6]> to be instantiated
and only break upon trying to sum() these?

I was hoping that specialization would fix this, but whenever
I try to move the sum() function out of the template declaration
and make it a

template<> simple_vector<int>::sum() {
}

the compiler complains that the template does not contain a
function called sum(). But of course leaving a declaration of
sum as T sum() within the template declaration will lead to
the same error that sum() can't return an array.

I've googled c.l.c++ only to begin to suspect that I need function
specialization and not template specialization and that it cannot
be done. Is it so?

NB: this is only a stripped-down example. Suggestions to use
a std::vector<double> instead of double[6] or to create a double6
struct won't fix my problem.

So in general: what I need is a template, a few functions of
which need to look differently for different T's, where T is the
template typename parameter. Or better -- can I make some
template member function hidden for certain T's, for which
these functions don't make sense/become illegal?

thanks in advance,
- J.


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #2
"Jacek Dziedzic" <jacek__NOSPAM__@janowo_NO_spam_.net> wrote in message
news:4097B595.2764F8D9@janowo_NO_spam_.net
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 trouble begins here:

T sum() {
// calculates and returns a sum of all elements of the vector
}
};

The trouble begins whenever I try to have a vector that would
hold elements of, say, double[6]. Trying to instantiate that
gives an error, because the return type of sum() becomes an
array, which is impossible.

Is there a simple way to let the user have instances of
simple_vector<int> for which the sum() operation makes sense
while also allowing simple_vector<double[6]> to be instantiated
and only break upon trying to sum() these?

I was hoping that specialization would fix this, but whenever
I try to move the sum() function out of the template declaration
and make it a

template<> simple_vector<int>::sum() {
}

the compiler complains that the template does not contain a
function called sum(). But of course leaving a declaration of
sum as T sum() within the template declaration will lead to
the same error that sum() can't return an array.

I've googled c.l.c++ only to begin to suspect that I need function
specialization and not template specialization and that it cannot
be done. Is it so?


You can return a pointer or reference to an array if a pointer or reference
would be acceptable for all types. Alternatively, you could make sum() a
friend of the class rather than a member.

Finally, you could specialise the entire class rather than attempting to
specialise just a member function. In that case you must declare and define
the entire class again for the particular type you are interested in. To do
this, you first declare the general class. Then you declare the specialised
version, which may but need not have anything in common with the general
case, e.g.,

#include <iostream>

template <typename T>
class simple_vector
{
T t1, t2;
public:
void print() { std::cout << t1 << '\n'; }
T sum()
{
return t1+t2;
}
};
template <>
class simple_vector<double[6]>
{
double d[6];
public:
simple_vector()
{
for (int i=0; i<6; ++i)
d[i] = i*i;
}
void print()
{
for (int i=0; i<6; ++i)
std::cout << d[i]<< '\n';
}
};
int main()
{
simple_vector<double[6]> v;
v.print();
return 0;
}

--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

Jul 22 '05 #3

"Leor Zolman" <le**@bdsoft.com> wrote in message
news:ed********************************@4ax.com...
On Tue, 04 May 2004 17:24:05 +0200, Jacek Dziedzic
<jacek__NOSPAM__@janowo_NO_spam_.net> wrote:
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 trouble begins here:

T sum() {
// calculates and returns a sum of all elements of the vector
}
};

The trouble begins whenever I try to have a vector that would
hold elements of, say, double[6]. Trying to instantiate that
gives an error, because the return type of sum() becomes an
array, which is impossible.


I think you're SOL with respect to elements of type double[6], because
they're not assignable or copyable. You can't put things into containers
that aren't assignable/copyable. I feel like an idiot, because I've spent
an hour or more playing with this, until I finally got an error that made
me realize there's no way it can ever work.

Perhaps you can make do with storing vectors instead of the arrays of 6
doubles?
-leor


boost have a fixed size array class, specifically design to be usable in the
STL. Presumably it would be usable with the OPs code as well.

http://www.boost.org/doc/html/array.html

john
Jul 22 '05 #4
On Tue, 4 May 2004 17:25:06 +0100, "John Harrison"
<jo*************@hotmail.com> wrote:
Perhaps you can make do with storing vectors instead of the arrays of 6
doubles?
-leor


boost have a fixed size array class, specifically design to be usable in the
STL. Presumably it would be usable with the OPs code as well.

http://www.boost.org/doc/html/array.html


Sure, I think any true objects (that satisfy the container requirements)
would be fine. The thing that was deceptive about trying to store naked
arrays is that you can get "just so far", before you actually try to do
anything useful, and it compiles. The trouble first showed up for me, in
the case of the OP's example, when I attempted to create constructors for
his container class...if there's only a default ctor, then you'd have to
add elements using push_back or insert... but you /can't/ because you can't
pass an array to a function:
simple_vector<double[6]> v; // OK
double d[6] = {...};
v.push_back(d); // Bzzzzzt! You lose!

So my next clever idea was to create a ctor that takes a size, in order to
"pre-allocate" the arrays:

simple_vector<double[6]> v(5); // Bzzzt!

then just go in and fill in the values one at a time with assignment
statements a la:
v[0][0] = .2;
v[0][1] = .5; // etc.

The assignments would work (I guess, although I never got to the point of
being able to find out...), but the constructor can't--because it would
need to be able to default initialize each double[6], which of course can't
be done. So the entire house of cards comes tumbling down.

I figure you (John) understands this, I was just spelling it out for the
benefit of anyone else (like me) who actually tried to make this work as
advertised. I doubt I'll make the same mistake again ;-)
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #5
John Carson wrote:

You can return a pointer or reference to an array if a pointer or reference
would be acceptable for all types.
No, I can't afford the performance loss. My simple_vector class
serves as an envelope for traditional arrays of
doubles/ints/double[6]'s I get from somewhere else and for my
own arrays that I'd like to be handled in a clean manner.
Performance, however, is critical to me (this is a part of a scientific
computation)
Alternatively, you could make sum() a
friend of the class rather than a member.

Finally, you could specialise the entire class rather than attempting to
specialise just a member function. In that case you must declare and define
the entire class again for the particular type you are interested in. To do
this, you first declare the general class. Then you declare the specialised
version, which may but need not have anything in common with the general
case, e.g.,

#include <iostream>

template <typename T>
class simple_vector
{
T t1, t2;
public:
void print() { std::cout << t1 << '\n'; }
T sum()
{
return t1+t2;
}
};
template <>
class simple_vector<double[6]>
{
double d[6];
public:
simple_vector()
{
for (int i=0; i<6; ++i)
d[i] = i*i;
}
void print()
{
for (int i=0; i<6; ++i)
std::cout << d[i]<< '\n';
}
};
int main()
{
simple_vector<double[6]> v;
v.print();
return 0;
}


The trouble is, I'd have to repeat 30KB of source only to change
a single line in the second occurrence...

- J.
Jul 22 '05 #6
John Harrison wrote:
"Leor Zolman" <le**@bdsoft.com> wrote in message
news:ed********************************@4ax.com...
I think you're SOL with respect to elements of type double[6], because
they're not assignable or copyable. You can't put things into containers
that aren't assignable/copyable. I feel like an idiot, because I've spent
an hour or more playing with this, until I finally got an error that made
me realize there's no way it can ever work.
My answer to Leor here (my newsserver is still allergic to your
posts, so I can only see replies to your replies)...

If you can't put things that aren't assignable copyable into
containers, then I guess my simple_vector class is not a container.
Within the realm of my class I don't need the 'thing' to be
copyable or assignable.

I realize sum() would never work for double[6], because you
can't return them. The thing is I want sum() to work for some
chosen types (like int and double) *only*. I don't care if
it's meaningless to call simple_vector<double[6]>::sum(),
if only it would compile... In other words I'd like this
to work:

double s;
simple_vector<double> v(10);
s=v.sum()

and this to work

simple_vector<double[6]> v(10);
// note: no usage of sum()

and this to either not compile or produce a runtime error:

simple_vector<double[6]> v(10);
v.sum();
Perhaps you can make do with storing vectors instead of the arrays of 6
doubles?

Unfortunately not. The 'thing' needs to be POD, as it is
raw-memory-copied between processors on a parallel system.
Also I can't afford the memory overhead of std::vector
(these simple_vectors run into GB's of memory).

I'd rather make double[6] into a SixDoubles class or
struct if no other solution emerges.
boost have a fixed size array class, specifically design to be usable in the
STL. Presumably it would be usable with the OPs code as well.


You mean instead of the double[6] or the whole simple_vector?
If the latter, no way. This simple_vector has very specific
functionality that I'm almost sure no 3rd party implementation
provides. If the former, then I'd rather make that double[6] into
a struct.

- J.
Jul 22 '05 #7
On Tue, 04 May 2004 21:58:46 +0200, Jacek Dziedzic
<ja*************@janowo.net> wrote:
John Harrison wrote:
"Leor Zolman" <le**@bdsoft.com> wrote in message
news:ed********************************@4ax.com...
I think you're SOL with respect to elements of type double[6], because
they're not assignable or copyable. You can't put things into containers
that aren't assignable/copyable. I feel like an idiot, because I've spent
an hour or more playing with this, until I finally got an error that made
me realize there's no way it can ever work.

My answer to Leor here (my newsserver is still allergic to your
posts, so I can only see replies to your replies)...


Darn. I'm sending you an email copy of this post, then. I don't know why
your news server hates me, but if you ever figure it out, please let me
know if there's anything I can do about it. I just use Agent, and I post
from comcast.net...

If you can't put things that aren't assignable copyable into
containers, then I guess my simple_vector class is not a container.
Within the realm of my class I don't need the 'thing' to be
copyable or assignable.


Whoops, my own confusion there. In the code I was playing around with, I
had simple_vector inherit from std::vector, and then I somehow got that
turned around in my head to where I thought the idea came from your code.
Now I see that it didn't. Sorry!

I may not have enough time to come up with an answer before someone else
gives you a better one (my newsgroup window for today is about to close),
but I thought I'd at least explain why my previous posts seemed so out in
left field.
-leor
--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #8
* Jacek Dziedzic <jacek__NOSPAM__@janowo_NO_spam_.net> schriebt:

Is there a simple way to let the user have instances of
simple_vector<int> for which the sum() operation makes sense
while also allowing simple_vector<double[6]> to be instantiated
and only break upon trying to sum() these?


#include <vector>
#include <iostream>

struct DoubleArray6
{
double elem[6];
};

int main()
{
static DoubleArray6 const x = {10, 20, 30, 40, 50, 60};

std::vector<DoubleArray6> v;
v.push_back( x );
for( size_t i = 0; i < 6; ++i )
{
std::cout << v[0].elem[i] << std::endl;
}
}

Just use your own vector class instead of std::vector.

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #9
Alf P. Steinbach wrote:
* Jacek Dziedzic <jacek__NOSPAM__@janowo_NO_spam_.net> schriebt:
Is there a simple way to let the user have instances of
simple_vector<int> for which the sum() operation makes sense
while also allowing simple_vector<double[6]> to be instantiated
and only break upon trying to sum() these?

#include <vector>
#include <iostream>

struct DoubleArray6
{
double elem[6];
};

int main()
{
static DoubleArray6 const x = {10, 20, 30, 40, 50, 60};

std::vector<DoubleArray6> v;
v.push_back( x );
for( size_t i = 0; i < 6; ++i )
{
std::cout << v[0].elem[i] << std::endl;
}
}

Just use your own vector class instead of std::vector.


Yes, that was the sort-of-solution I came up with also.
What I don't like about it, however, is that I've already
done it with double[3], having now a simple Vect3d class,
now I'd have to add something like Vect6d. I'd go with
this for now, because time presses me, but I had really hoped
there was some solution more closer to the class itself
than to the user code using the class...

Or in other words... This solution is along the lines of
"Here's a simple_vector class template, it holds objects
of the type you desire, except for arrays. You can't store
arrays in it, unless you pack them in a separate type.
Alas, you'll need one extra type for each kind of array
you want, or you'll need to use a vector and face the
overhead."

I was hoping for a solution that would fix the template and
go like "Here'a simple_vector class template, it holds
objects of the type you desire, including arrays. Be warned
though that some methods of this templated class are of no
use on some types, so don't try to sum() arrays for example."

I must admit I had only a vague idea about template specialization
and actually thought that was a very easy task. I mean -- can't
you really have a template that works the same for all supported
types, save one, for which it has one function redefined? That
is, without having to write the 99% of the template twice?

Can someone help on the template-like solution?

TIA,
- J.
Jul 22 '05 #10
On Tue, 04 May 2004 21:58:46 +0200, Jacek Dziedzic
<ja*************@janowo.net> wrote:
I realize sum() would never work for double[6], because you
can't return them. The thing is I want sum() to work for some
chosen types (like int and double) *only*. I don't care if
it's meaningless to call simple_vector<double[6]>::sum(),
if only it would compile... In other words I'd like this
to work:

double s;
simple_vector<double> v(10);
s=v.sum()

and this to work

simple_vector<double[6]> v(10);
// note: no usage of sum()

and this to either not compile or produce a runtime error:

simple_vector<double[6]> v(10);
v.sum();


Okay, all I can think of is to take the sum functionality out of the class
and make it into a non-member function. Here's an implementation where the
version of sum taking the simple_vector<double[6]> actually does something
useful:

#include <iostream>
using namespace std;

template <typename T>
class simple_vector {
public:
simple_vector(int i) : vsize(i), ptr(new T[i]) {}
int size() const { return vsize; }
T &operator[](int index) { return ptr[index]; }
T const &operator[](int index) const { return ptr[index]; }
public:
T *ptr;
int vsize;
};
template<typename T>
T sum(simple_vector<T> s) {
// calculates and returns a sum of all elements of the vector
T result = 0;
for (int i = 0; i < s.size(); ++i)
result += s.ptr[i];
return result;
}

template<typename T, int N>
void sum(simple_vector<T[N]> sv, T *result)
{
for (int i = 0; i < N; ++i)
{
T total = 0;
for (int j = 0; j < sv.size(); j++)
total += sv[j][i];
result[i] = total;
}
}
int main()
{
simple_vector<double> v(10);
double s;
s = sum(v);
cout << "sum(v) = " << s << endl;

simple_vector<double[2]> v2(2);
v2[0][0] = .2;
v2[0][1] = .2;
v2[1][0] = .3;
v2[1][1] = .3;
double result[2];
sum(v2, result);
cout << "result[0] = " << result[0] << endl;
cout << "result[1] = " << result[1] << endl;

return 0;
}
HTH,
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #11
Jacek Dziedzic <ja*************@janowo.net> wrote in news:c7924r$6rj$1
@korweta.task.gda.pl:
Alf P. Steinbach wrote:
* Jacek Dziedzic <jacek__NOSPAM__@janowo_NO_spam_.net> schriebt:
Is there a simple way to let the user have instances of
simple_vector<int> for which the sum() operation makes sense
while also allowing simple_vector<double[6]> to be instantiated
and only break upon trying to sum() these?

#include <vector>
#include <iostream>

struct DoubleArray6
{
double elem[6];
};

int main()
{
static DoubleArray6 const x = {10, 20, 30, 40, 50, 60};

std::vector<DoubleArray6> v;
v.push_back( x );
for( size_t i = 0; i < 6; ++i )
{
std::cout << v[0].elem[i] << std::endl;
}
}

Just use your own vector class instead of std::vector.


Yes, that was the sort-of-solution I came up with also.
What I don't like about it, however, is that I've already
done it with double[3], having now a simple Vect3d class,
now I'd have to add something like Vect6d. I'd go with
this for now, because time presses me, but I had really hoped
there was some solution more closer to the class itself
than to the user code using the class...

Or in other words... This solution is along the lines of
"Here's a simple_vector class template, it holds objects
of the type you desire, except for arrays. You can't store
arrays in it, unless you pack them in a separate type.
Alas, you'll need one extra type for each kind of array
you want, or you'll need to use a vector and face the
overhead."

I was hoping for a solution that would fix the template and
go like "Here'a simple_vector class template, it holds
objects of the type you desire, including arrays. Be warned
though that some methods of this templated class are of no
use on some types, so don't try to sum() arrays for example."

I must admit I had only a vague idea about template specialization
and actually thought that was a very easy task. I mean -- can't
you really have a template that works the same for all supported
types, save one, for which it has one function redefined? That
is, without having to write the 99% of the template twice?

Can someone help on the template-like solution?


You could specialise the simple_vector template for array types.
E.g.

template <class T>
class simple_vector {
T sum() { ... }
};

template <class T, int n>
class simple_vector<T[n]> {
T* sum() { ... }
};

Though, not all compilers support such specialisations, unfortunately.

Cheers!
--
:: bartekd [at] o2 [dot] pl

Jul 22 '05 #12
bartek <sp******************@o2.pl> wrote in
news:Xn*********************************@153.19.25 1.200:

(...)
You could specialise the simple_vector template for array types.
E.g.

template <class T>
class simple_vector {
T sum() { ... }
};

template <class T, int n>
class simple_vector<T[n]> {
T* sum() { ... }
};

Though, not all compilers support such specialisations, unfortunately.


OK, please forget it. sum() returning T* is stupid... stupid me...

--
:: bartekd [at] o2 [dot] pl

Jul 22 '05 #13
"Jacek Dziedzic" <ja*************@janowo.net> wrote in message
news:c7**********@korweta.task.gda.pl
John Carson wrote:
>
Alternatively, you could make sum() a
friend of the class rather than a member.
You didn't comment on this. Performances issues again? (I wouldn't know.)
Finally, you could specialise the entire class rather than
attempting to specialise just a member function.


The trouble is, I'd have to repeat 30KB of source only to change
a single line in the second occurrence...


I am not certain of this, but I think that the repetition only makes a
difference to your source code, not your binary. If you instantiate a single
template class for, say, int and double[6], then what you get is effectively
two classes, one for int and one for double[6]. The basic difference is just
that the compiler has written them rather than you. The template itself
should not go into the source code, just the instantiations of it.
Accordingly, it shouldn't make a difference to the size of the binary
whether both instantiations use the same template or each draws on its own
template. Of course, it is less elegant from a coding standpoint to have to
repeat an entire template class.

In any event, a better solution is to template the return type of the sum
function and then provide a specialisation of the sum function for
double[6]. Note that the second template parameter defaults to the first
parameter.

template <typename T, typename R=T>
class simple_vector
{
T t1,t2;
public:
R sum()
{
return t1+t2;
}
};

template <>
int simple_vector<double[6], int>::sum()
{
return 0;
}

You declare an instance of the class for an int with:

simple_vector<int> v1;

More generally, for any type X for which the default sum function makes
sense, you declare an instance with

simple_vector<X> v1;

By contrast, you declare an instance of the class for double[6] with:

simple_vector<double[6], int> v2;
--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

Jul 22 '05 #14
"John Carson" <do***********@datafast.net.au> wrote in message
news:40********@usenet.per.paradox.net.au
In any event, a better solution is to template the return type of the
sum function and then provide a specialisation of the sum function for
double[6]. Note that the second template parameter defaults to the
first parameter.

template <typename T, typename R=T>
class simple_vector
{
T t1,t2;
public:
R sum()
{
return t1+t2;
}
};

template <>
int simple_vector<double[6], int>::sum()
{
return 0;
}

You declare an instance of the class for an int with:

simple_vector<int> v1;

More generally, for any type X for which the default sum function
makes sense, you declare an instance with

simple_vector<X> v1;

By contrast, you declare an instance of the class for double[6] with:

simple_vector<double[6], int> v2;

Better still is to make the specialisation with R==void rather than R==int.
When T==double[6], calling sum() will compile but it will not compile if you
assign the return value to anything.

template <typename T, typename R=T>
class simple_vector
{
T t1,t2;
public:
R sum()
{
return t1+t2;
}
};

template <>
void simple_vector<double[6], void>::sum()
{}
simple_vector<int> v1;
simple_vector<double[6], void> v2;

int main()
{
v1.sum(); // compiles
v2.sum(); // compiles
double d = v2.sum(); // won't compile
return 0;
}
--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

Jul 22 '05 #15
On Wed, 5 May 2004 13:17:00 +1000, "John Carson"
<do***********@datafast.net.au> wrote:
"John Carson" <do***********@datafast.net.au> wrote in message
news:40********@usenet.per.paradox.net.au
In any event, a better solution is to template the return type of the
sum function and then provide a specialisation of the sum function for
double[6]. Note that the second template parameter defaults to the
first parameter.

template <typename T, typename R=T>
class simple_vector
{
T t1,t2;
public:
R sum()
{
return t1+t2;
}
};

template <>
int simple_vector<double[6], int>::sum()
{
return 0;
}


Nice! Having the 2nd template parameter default to the first is gorgeous.
Wish I'd thought of that ;-)
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #16
Jacek Dziedzic wrote:
...
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 trouble begins here:

T sum() {
// calculates and returns a sum of all elements of the vector
}
};

The trouble begins whenever I try to have a vector that would
hold elements of, say, double[6]. Trying to instantiate that
gives an error, because the return type of sum() becomes an
array, which is impossible.

Is there a simple way to let the user have instances of
simple_vector<int> for which the sum() operation makes sense
while also allowing simple_vector<double[6]> to be instantiated
and only break upon trying to sum() these?
...


You can probably use some traits-based technique. If you don't care for
a useable 'sum' in 'simple_vector<double[6]>', it can be done, for
example, as follows

template <typename T_> struct type_traits {
typedef T_ return_t;
};

template <> struct type_traits<double[6]> {
typedef void return_t;
};

template <typename T_>
class simple_vector : public math_object {
...
typename type_traits<T_>::return_t sum();
...
};

(Partial specialization can be used to cover all arrays, not just
'double[6]' as in the above example).

--
Best regards,
Andrey Tarasevich

Jul 22 '05 #17
Andrey Tarasevich wrote:
You can probably use some traits-based technique. If you don't care for
a useable 'sum' in 'simple_vector<double[6]>', it can be done, for
example, as follows
...


I just noticed that John Carson already suggested a similar approach.

--
Best regards,
Andrey Tarasevich

Jul 22 '05 #18

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

Similar topics

2
by: James Ying | last post by:
Following is the complete code demonstrating the issue: ===================== > cat tt.cc #include <iostream> template <class T> class Base { public: typedef T difference_type; };
2
by: Thomas Lorenz | last post by:
Hello, im working on a problem related to smart pointers. If the following is legal C++ A* a(new A()); B* b; b = a; I want to be able to do the following:
4
by: Ingo Nolden | last post by:
Hi, I want to write a template class that holds another class that uses the same template. This recursion should stop after a predefined number. I think it's either impossible or easy, but I...
12
by: mlimber | last post by:
This is a repost (with slight modifications) from comp.lang.c++.moderated in an effort to get some response. I am using Loki's Factory as presented in _Modern C++ Design_ for message passing in...
10
by: mast2as | last post by:
Is it possible to limit a template class to certain types only. I found a few things on the net but nothing seems to apply at compile time. template <typename T> class AClass { public:...
4
by: Howard Gardner | last post by:
// I think that there is no way to write the template "cant_write_me" in // this example. Would love to be wrong. // one of many approaches that won't work template< template< typename class...
4
by: Fei Liu | last post by:
#include <vector> #include <iostream> template <template <typename T, typename Allocclass C> struct A{ //C<Tc; //A(){ c=10; } void print(){ std::cout << "A" << std::endl; } };
2
by: tony | last post by:
Hello! I have this template class with a default type (please do not give too much importance to the actual code, it's just an example, it's not a useful implementation of anything nor a good...
4
by: KD | last post by:
I have a template function and I'm looking for a way to force the caller to specify the template parameters. In other words, I would like to turn off template parameter deduction. For example, ...
11
by: Juha Nieminen | last post by:
I'm writing an STL-style data container, and this problem is puzzling me. The following code should demonstrate the problem: //---------------------------------------------------------- #include...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
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
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
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.