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;
}
Live example.
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?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…