There is different behaviour in clang++ and g++ for the next program:
#include <type_traits>
#include <utility>
template< std::size_t index, typename type >
struct ref { type & value; };
template< std::size_t index, typename type >
type && get(ref< index, type > const & r)
{
return std::forward< type >(r.value);
}
template< typename F, typename ...types, std::size_t ...indices >
decltype(auto) apply_inverse(F & f, types &... values, std::index_sequence< indices... >)
{
struct : ref< indices, types >... {} refs{{values}...};
constexpr std::size_t top = sizeof...(indices) - 1;
return std::forward< F >(f)(get< top - indices >(refs)...);
}
template< typename F, typename ...types >
decltype(auto) apply_inverse(F && f, types &&... values)
{
return apply_inverse< F, types... >(f, values..., std::index_sequence_for< types... >{});
}
#include <iostream>
int main()
{
auto const print = [] (auto const &... value) -> std::ostream & { return (std::cout << ... << value); };
apply_inverse(print, 1, 2, 3) << std::endl;
}
It just tries to revert the arguments passed and applies some function to them.
For G++ it compiles fine, but for clang++ (even from trunk) it gives the following error:
error: no matching function for call to 'apply_inverse'
I think the reason is the fact, that in upper overloading there is a parameter after parameter pack in the function prototype. But types for all the arguments in arguments pack are explicitly specified.
Is it right for compiler to accept the code?