Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advantages of arrow syntax in function declaration

what are the advantages of using

template <typename L, typename R> 
auto getsum(L l, R r) -> decltype(l + r) {return l + r;}

over

 template <typename L, typename R>
 auto getsum(L l, R r) {return l +  r;}

isn't it compiled into the appropriate type during template instantiation?

like image 823
ferdinandutkin Avatar asked Dec 14 '22 08:12

ferdinandutkin


2 Answers

what are the advantages of using [trailing return type syntax] ?

A possible advantage: the trailing return type is SFINAE friendly.

Your getsum() function, with trailing return type (-> decltype( l + r )), is enabled only when exist an plus operator between l and r.

If you call it with a couple of arguments that doesn't support the sum (by example, a couple of std::vector's) you get a substitution failure that isn't an error (SFINAE).

So another getsum() function can be called.

The following is a full example that compile and where the "do something different" version is called from getsum(a, b)

#include <vector>

template <typename ... Ts>
auto getsum (Ts...)
 { /* do something different */ }

template <typename L, typename R> 
auto getsum (L l, R r) -> decltype( l + r )
 { return l + r; }

int main ()
 {
   std::vector<int> a, b;

   getsum(a, b);
 }

But if you remove the trailing return type

template <typename L, typename R> 
auto getsum (L l, R r) // <<--- no more tailing return type!!!
 { return l + r; }

the code doesn't compile anymore, because you don't have a substitution failure but an hard error.

like image 154
max66 Avatar answered Dec 16 '22 11:12

max66


An advantage obviously is shorter code.

But there are disadvantages, too: besides automatic return type deduction being available from C++14 only, there are cases when the return type cannot be deduced.

Suppose the complexity of the function is increased slightly:

template <typename L, typename R>
auto getsum(L l, R r) {
    if (l < 0)
        return 0;
    return l + r;
}

Now the following won't compile:

int main() {
    auto s = getsum(1L, 2); // error: inconsistent deduction for auto return type: 'int' and then 'long int'
}

We fix that by specifying the return type explicitly (for example, using the trailing return type syntax):

auto getsum(L l, R r) -> decltype(l + r) {
    if (l < 0)
        return 0;
    return l + r;
}

int main() {
    auto s = getsum(1L, 2);  // OK
}
like image 45
rustyx Avatar answered Dec 16 '22 12:12

rustyx