1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
#include <iostream>
#include <type_traits>
#include <tuple>
// determine the type of the last variadic parameter
template < typename... > struct last_t {} ;
// only one parameter T, T is the type of the last parameter
template < typename T > struct last_t<T> { using type = T ; } ;
// two or more parameters, discard the first parameter and apply recursively
template < typename FIRST, typename... REST >
struct last_t<FIRST,REST...> : last_t<REST...> {};
template < typename FN, typename... ARGS > void add( FN, ARGS&&... args )
{
// generate an error if the type of the last argument in the pack can't be converted to int
static_assert( std::is_convertible< typename last_t<ARGS...>::type, int >::value,
"last argument is not convertible to int" ) ;
constexpr std::size_t N = sizeof...(ARGS) ; // the number of variadic parameters in the pack
// extract the value at the end of the pack as an int
const int val = std::get<N-1>( std::tuple<ARGS&&...>( std::forward<ARGS>(args)... ) ) ;
std::cout << "last int argument: " << val << '\n' ;
}
int main()
{
add( []{}, 1, 2, "abc", 4 ) ; // last int argument: 4
add( []{}, 1, 2, "abc", 4, 5, 6 ) ; // last int argument: 6
add( []{}, 1 ) ; // last int argument: 1
add( []{}, 1, 2, "abc", 24.5 ) ; // last int argument: 24 (narrowing conversion to int)
// add( []{}, 1, 2, "abc", 4, "def" ) ; // *** error *** : static_assertion failed
// "last argument is not convertible to int"
}
|