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.
精彩评论