Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ returning more precise of two template arguments from function?

Tags:

c++

templates

I'm curious if there's any way to do this in C++. Let's say I have a templated vector class:

template <typename T>
class vector {          
public:
      vector(T a, T b, T c) : x(a), y(b), z(c) {}

      T x,y,z;
};

And then I have a templated addition operator:

template <typename A, typename B> 
vector<A> operator +(const vector<A> &a, const vector<B> &b) { 
   return vector<A>(a.x+b.x, a.y+b.y, a.z+b.z); 
}

I'm curious if it's possible to modify that operator so the result is whichever of the two types A and B is more precise, aside from manually specializing it.

For example:

vector<float>       + vector<double> would produce a vector<double>, 
vector<long double> + vector<float>  would produce a vector<long double>

My guess would be that there's no automatic support for this in C++, but I thought I'd ask.

like image 990
gct Avatar asked Feb 01 '11 18:02

gct


3 Answers

There isn't any built-in support in the form of a library, but you can accomplish this using the conditional (?:) operator.

In reply to another answer, Johannes Schaub posted a promote<T, U> template that wraps the logic up quite nicely. With the template, you should be able to write:

template <typename A, typename B>  
vector< typename promote<A, B>::type >
operator+(const vector<A> &a, const vector<B> &b) 
{     
    return vector< typename promote<A, B>::type >(a.x+b.x, a.y+b.y, a.z+b.z);  
} 
like image 50
James McNellis Avatar answered Oct 21 '22 02:10

James McNellis


in C++0x, you could say:

template <typename A, typename B> 
auto operator +(const vector<A> &a, const vector<B> &b) -> vector<decltype(a.x + b.x)>
{
    //...
}

In C++03, you need to define all the combinations yourself, although you can do it in a reusable op_traits scheme that can be applied to a variety of different operators. James McNellis provides some details on this in his answer

like image 28
Ben Voigt Avatar answered Oct 21 '22 02:10

Ben Voigt


Andrei Alexandrescu discussed this in his 1st April 2001 DDJ article Generic: Min and Max Redivivus.

In short, the general problem is very complex.

Andrei used 80 lines of support code, those lines in turn relying on the Loki library.

Cheers & hth,.

like image 32
Cheers and hth. - Alf Avatar answered Oct 21 '22 01:10

Cheers and hth. - Alf