How to write the return type of return correctly?

Suppose I have this function template:

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

Of course, this function needs an end inverse type, which, given the purpose of the function, I really could not get rights.

It is assumed that this function must use arg , perform some operation with the arg and T2 objects, and use the result of this operation as the return value of the function. Obviously, the return type of the DoSomething() must (compatible) match the return type of the operation performed for arg and the T2 object.

Suppose again that we are doing DoSomething() doing some real operation, such as multiplication. Then we will write DoSomething() as 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 can I then form a return type for this?


PS: I tried using decltype(arg * T2) , decltype(T1 * T2) and decltype(T1::operator * (T2)) and some other fancy decltype images for return type return value. None of them worked.

+7
source share
1 answer

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 may not have a default constructor, so decltype(arg *T2()) may not work.

But then I also notice that if T2 does not have a default constructor, then you could not write T2 t2Obj . Therefore , if T2 is required to create a default constructor, you can simply write this:

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

which should also work if you want T2 have a default constructor!

+10
source

All Articles