Question

Suppose I have this function template:

template<typename T1, typename T2>
auto DoSomething(const T1& arg);

Of course this function needs a trailing return type which, considering the function's purpose, I really could not get right.

What this function is supposed to do is to use arg, do some operation with arg and a T2 object and use the result of that operation as the return value of the function. Clearly, DoSomething()'s return type must (compatibly) match with the return type of the operation done for arg and the T2 object.

Suppose again that we make DoSomething() do some real operation, like multiplication. We would then write DoSomething() as like the code below:

template<typename T1, typename T2>
auto DoSomething(const T1& arg) -> /* trailing return-type */ {
    T2 t2Obj;   // Or have it obtained in some other way
    return arg * t2Obj;
}

How should I then form the trailing return-type for this?


P.S.: I've tried using decltype(arg * T2), decltype(T1 * T2) and decltype(T1::operator * (T2)) and some other really bizarre-looking decltypes for the trailing-return type. None of them worked.

Was it helpful?

Solution

You should use decltype and std::declval<> as:

template<typename T1, typename T2>
auto DoSomething(const T1& arg) -> decltype(arg * std::declval<T2>())
{
    T2 t2Obj;   // Or have it obtained in some other way
    return arg * t2Obj;
}

because T2 might not have default constructor, so decltype(arg *T2()) may not work.

But then I also notice that if T2 doesn't have default constructor, then you would not be able to write T2 t2Obj either. So if you require T2 to have default constructor, then you can simply write this:

-> decltype(arg *T2()) //requirement : T2 must have default constructor

that should also work if you require T2 to have default constructor!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top