开发者

c++ generalized operator templating

I'm doing some numerical simulations where it is nice to overload operations on vectors (similar to valarrays). For example, I can write

template <typename T>
vector<T> operator*(const vector<T>& A, const vector<T>& B){
   //blah blah
}

But what if I want to generalize this template so as to act on two different types of vectors and (potentially) return a third type? I.e. I want to w开发者_运维技巧rite

template <typename T, template U, template V>
vector<V> operator*(const vector<T>& A, const vector<U>& B){
   //blah blah
}

Now, the above does indeed work if I use the operator in a situation "A*B" where A and B are distinct types and return a another distinct type. However, if A and B are the same type, it does not work. Certainly I could define different templates for each combination (i.e. T only, or T and U only, or T, U, and V) but that seems ugly. Is there a way I can use a single template expression of the T,U, and V variety given above and make it work even if "A", "B", and "A*B" are all the same types (or have only 2 different types?)


Now, the above does indeed work if I use the operator in a situation "A*B" where A and B are distinct and return a different type.

To be honest, this doesn't make sense. Your template shouldn't work at all because V cannot be deduced and it is the third template parameter. If you had written:

template <typename V, template T, template U>
vector<V> operator*(const vector<T>& A, const vector<U>& B){
   //blah blah
}

This would "work" but only if you explicitly specified V, something like

operator*<double>(A, B); //where A is vector<int> and B is vector<float>, for example

Surely you want to return a vector<V> where V is the type of the expression T()*U(). This is possible to do in C++11, but not trivially in C++03( I mean, you could do some type-traiting at best). Here's how it's done in C++11:

template <typename T, template U>
vector<decltype(T()*U())> operator*(const vector<T>& A, const vector<U>& B)  
{
   //blah blah
}

HTH


This can work in C++0x with decltype.

template <typename T, template U> 
vector<decltype(declval<T>() + declval<U>())> 
operator*(const vector<T>& A, const vector<U>& B){
   //blah blah
}

Without using this mechanism- and presuming that T and U do not provide their own mechanism- you can't do something like this. You can only handle the situation where T, U, and the return type are all the same type. You can, however, deal with primitive types- there's a Boost type trait for the result of applying operators like + to various primitive types to find the promoted type.


As others have pointed out you can use decltype to achieve this. C++0x also provides the template common_type which deduces a type to which all it template arguments can be coerced without any specific arithmetic operation. So it can also be used if no overloaded operators are available for the argument types.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜