We can write a flag to check if the type is a pointer or a non-constant reference:
template <typename T> using is_pointer_or_ref = std::integral_constant<bool, std::is_pointer<T>::value || (std::is_lvalue_reference<T>::value && !std::is_const<typename std::remove_reference<T>::type>::value)>;
Then we can write a tag to test this for a parameter package using Jonathan and_ :
template<typename... Conds> struct and_ : std::true_type { }; template<typename Cond, typename... Conds> struct and_<Cond, Conds...> : std::conditional<Cond::value, and_<Conds...>, std::false_type>::type { }; template <typename... Ts> using are_pointer_or_ref = and_<is_pointer_or_ref<Ts>...>;
Now we can use std::enable_if to check the type:
template<typename ... Types, typename std::enable_if<are_pointer_or_ref<Types...>::value>::type* = nullptr> void F(Types&&... args){}
Note that forwarding reference is necessary to determine the category of argument values, so link checking works correctly.
Live demo
source share