Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > template function with automatically templatized return type.

Reply
Thread Tools

template function with automatically templatized return type.

 
 
Daniel Pitts
Guest
Posts: n/a
 
      01-30-2009
I have a Vector (as in math vector) template class.

template <typename component_t>
class Vector { /*...*/ };

It defines what you might expect for operators: =, [] +, -, * (as a
scalar multiply), /, etc...

I have some type which the result of (x*x) is not the same type as x.

OtherType operator*(const SomeType &, const SomeType &).

I would like to be able to define a generic operator* for Vector such
that the following works:

const Vector<OtherType> n = Vector<SomeType>() * SomeType();

I tried

template<typename component_in_t,
typename component_out_t, typename scalar_t>
Vector<component_out_t> operator *(const Vector<component_in_t> &in,
scalar_t scalar) {
Vector<component_out_t> result;
for (int i = 0; i < dimensions; ++i) {
result[i] = in[i]*scalar;
}
return result;
}

But my compiler can't infer component_out_t.

Is there any way to do this?

Thanks,
Daniel.
--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
 
Reply With Quote
 
 
 
 
Noah Roberts
Guest
Posts: n/a
 
      01-30-2009
Daniel Pitts wrote:

> I tried
>
> template<typename component_in_t,
> typename component_out_t, typename scalar_t>
> Vector<component_out_t> operator *(const Vector<component_in_t> &in,
> scalar_t scalar) {
> Vector<component_out_t> result;
> for (int i = 0; i < dimensions; ++i) {
> result[i] = in[i]*scalar;
> }
> return result;
> }
>
> But my compiler can't infer component_out_t.


How could it?

>
> Is there any way to do this?


No.
 
Reply With Quote
 
 
 
 
Noah Roberts
Guest
Posts: n/a
 
      01-30-2009
Daniel Pitts wrote:
> I have a Vector (as in math vector) template class.
>
> template <typename component_t>
> class Vector { /*...*/ };
>
> It defines what you might expect for operators: =, [] +, -, * (as a
> scalar multiply), /, etc...
>
> I have some type which the result of (x*x) is not the same type as x.
>
> OtherType operator*(const SomeType &, const SomeType &).
>
> I would like to be able to define a generic operator* for Vector such
> that the following works:
>
> const Vector<OtherType> n = Vector<SomeType>() * SomeType();


Actually, there probably is a way to do this but it's going to be some
sort of magic that I don't know. Clearly not what you've started with.
You need to somehow retrieve the OtherType type from metafunction
programming so that you can tell the operator * for vector * type what
to return.

So, get learning MPL and dig through the boost::type_traits library that
will be part of the next standard.

One easy method, but one that doesn't scale well, would be to create a
trait for "sometype" that is like "multiplication_type<X>" that returns
OtherType for SomeType.
 
Reply With Quote
 
Vidar Hasfjord
Guest
Posts: n/a
 
      01-31-2009
On Jan 30, 6:55*pm, Daniel Pitts
<(E-Mail Removed)> wrote:
> I have a Vector (as in math vector) template class.
>
> template <typename component_t>
> class Vector { /*...*/ };
>
> It defines what you might expect for operators: =, [] +, -, * (as a
> scalar multiply), /, etc...
>
> I have some type which the result of (x*x) is not the same type as x.
>
> OtherType operator*(const SomeType &, const SomeType &).
>
> I would like to be able to define a generic operator* for Vector such
> that the following works:
>
> const Vector<OtherType> n = Vector<SomeType>() * SomeType();
>
> I tried
>
> template<typename component_in_t,
> * * * * *typename component_out_t, typename scalar_t>
> Vector<component_out_t> operator *(const Vector<component_in_t> &in,
> * * * * * * * * * * * * * * * * * * scalar_t scalar) {
> * * Vector<component_out_t> result;
> * * for (int i = 0; i < dimensions; ++i) {
> * * * result[i] = in[i]*scalar;
> * * }
> * * return result;
>
> }
>
> But my compiler can't infer component_out_t.
>
> Is there any way to do this?


Yes. While C++ doesn't directly support overloading on return type,
you can achieve the effect by returning a proxy that has conversion
operators for the required return types. The conversion operator then
performs the operation. For example:

const int dimensions = 2;

template <typename T>
struct Vector
{
T v_ [dimensions];
T& operator [] (int i) {return v_ [i];}
const T& operator [] (int i) const {return v_ [i];}
};

template <typename T1, typename T2>
struct VectorMultiplication
{
const Vector <T1>* v_;
T2 s_;

VectorMultiplication (const Vector <T1>& v, T2 s)
: v_ (&v), s_ (s) {}

template <typename T3>
operator Vector <T3> () const {
Vector <T3> r = {};
for (int i = 0; i < dimensions; ++i)
r [i] = (*v_) [i] * s_;
return r;
}
};

template <typename T1, typename T2>
VectorMultiplication <T1, T2>
operator * (const Vector <T1>& v, T2 s)
{
return VectorMultiplication <T1, T2> (v, s);
}

// Test

#include <iostream>
#include <iterator>
#include <algorithm>

using namespace std;

template <typename T>
ostream& operator << (ostream& os, const Vector <T>& v)
{
copy (&v [0], &v [0] + dimensions,
ostream_iterator <T> (os, " "));
return os;
}

void test_overloaded_return_type ()
{
Vector <short> v = {1, 2};
cout << v << endl; // 1 2

Vector <int> r = v * 2;
cout << r << endl; // 2 4
}

You can extend the proxy to a full expression template to optimize
your vector operations. Look up "expression template" for more
information.

Regards,
Vidar Hasfjord
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Templatized function call interpreted as 'operator<' on gcc kcsasquatch C++ 2 08-31-2010 07:24 PM
retrieving templatized object via singleton getInstance using generic template parameters gary.bernstein@gmail.com C++ 3 06-06-2007 03:25 AM
Invoking templatized base class constructor from templatized derived class constructor mrstephengross C++ 5 05-18-2005 07:12 PM
Templatized 'Random' member function. ma740988 C++ 3 11-06-2004 07:16 PM
Can a template function return a template type? Damon C++ 2 12-15-2003 12:56 PM



Advertisments