Trailing Return Type Using decltype with a Variadic Template Function
While attempting to implement a basic adder function that accumulates the arguments and returns a sum with an appropriate type, a user encountered issues with the compiler's inability to deduce the return type correctly.
Code Snippet:
template <class T, class P...> auto sum(const T& t, const P&... p) -> decltype(t + sum(p...)) { return t + sum(p...); }
With the above code, the compiler struggles to resolve the return type when more than two arguments are involved. To address this, the user modified the function declaration:
template <class T, class P...> T sum(const T& t, const P&... p);
This modification fixed the issue but introduced another problem: the function returned an integer for mixed-type arguments, which was not desired.
Discussion and Resolution:
The problem arises because the trailing return type using decltype is only considered declared after the return type is specified. However, in this case, the return type depends on the recursive call to sum.
To resolve this, a custom traits class is introduced:
template<class T> typename std::add_rvalue_reference<T>::type val(); template<class T> struct id{typedef T type;}; template<class T, class... P> struct sum_type; template<class T> struct sum_type<T> : id<T> {}; template<class T, class U, class... P> struct sum_type<T,U,P...> : sum_type< decltype( val<const T&>() + val<const U&>() ), P... > {};
By replacing decltype with typename sum_type
template<class T, class U, class... P> struct sum_type<T,U,P...> : id<decltype( val<T>() + val<typename sum_type<U,P...>::type>() )>{};
With these modifications, the adder function accurately accumulates arguments and returns the expected sum with the correct type.
The above is the detailed content of How can I ensure correct return type deduction with a variadic template function using trailing return type and `decltype`?. For more information, please follow other related articles on the PHP Chinese website!