Reputation: 198
I stumbled upon this some time ago and I finally need to get an answer to this!
The problem is as follows:
#include <iostream>
using namespace std;
template <class FIRST, class SECOND>
FIRST multiply(FIRST a, SECOND b){
return a * b;
}
int main(){
int x = 39;
double y = 38.38;
cout << multiply(x, y) << endl;
}
In this C++ code I have two template parameters and the return type of the function is the type of one parameter. My problem with that is that the return type has to be (in this case) the same type like the variable a
is. I tried it with a THIRD template parameter but it gave me an compiling error, could anyone please explain this to me?
I don't want to make it generally a long
or something, I want the return type to be the 'biggest' type of the variables passed, so that it will work with chars and strings as well (for those I would obviously do another operation or something, this is only an example).
Upvotes: 6
Views: 8190
Reputation: 154025
The canonical approach to deal with situations like this is to return the appropriate type returned from the result of the operation called:
template <typename FIRST, typename SECOND>
auto multiply(FIRST a, SECOND b) -> decltype(a * b) {
return a * b;
}
This use-case is pretty much the motivating example for adding late return types: the result type of an operation can be entirely non-predictable. This leads to two needs:
decltype(expr)
does: it yields the type of what expr
is declared to be: when expr
is a function call you'd look at the function declaration and that's what decltype(expr)
yields (well, there are some complexities in there).To actually formulate expr
it is frequently necessary to get hold of function arguments. Thus, a new approach to declare function was introduced:
auto
function-name(
args) ->
return-type
The auto
keyword is merely indicating that the function will use a late return type. The function-name and args are used the same as in other functino declaration. The return-type then follows at a point where parameter names can be used, i.e., after the ->
is the return->type which is is normally in front of the function declaration.
Put differently, if return-type does not refer to the names of arguments, the declaration above is equivalent to this declaration:
return-type function-name(
args)
If return-type refers to a name introduced in args you'd need to deal with getting object of the appropriate types, e.g., using std::declval<T>()
.
Upvotes: 10
Reputation: 15518
You can use
typename std::common_type<FIRST,SECOND>::type
as return type of your arithmetic expression.
Upvotes: 2