这是一个从重载集中删除函数的版本,而不是给出静态断言。这允许您提供在类型不完全相同时可以使用的函数的其他重载,而不是无法避免的致命 static_assert。
#include <type_traits>
template<typename... T>
struct all_same : std::false_type { };
template<>
struct all_same<> : std::true_type { };
template<typename T>
struct all_same<T> : std::true_type { };
template<typename T, typename... Ts>
struct all_same<T, T, Ts...> : all_same<T, Ts...> { };
template<typename... T>
typename std::enable_if<all_same<T...>::value, void>::type
func(T...)
{ }
如果您想支持完美转发,您可能希望在检查它们之前衰减类型,以便函数将接受左值和右值参数的混合,只要它们具有相同的类型:
template<typename... T>
typename std::enable_if<all_same<typename std::decay<T>::type...>::value, void>::type
func(T&&...)
{ }
或者,如果您有测试逻辑连接的通用特征,您可以使用std::is_same 来完成,而不是编写自己的all_same:
template<typename T, typename... Ts>
typename std::enable_if<and_<is_same<T, Ts>...>::value, void>::type
func(T&&, Ts&&...)
{ }
因为这需要至少一个参数,所以您还需要另一个重载来支持零参数情况:
void func() { }
and_ 助手可以这样定义:
template<typename...>
struct and_;
template<>
struct and_<>
: public std::true_type
{ };
template<typename B1>
struct and_<B1>
: public B1
{ };
template<typename B1, typename B2>
struct and_<B1, B2>
: public std::conditional<B1::value, B2, B1>::type
{ };
template<typename B1, typename B2, typename B3, typename... Bn>
struct and_<B1, B2, B3, Bn...>
: public std::conditional<B1::value, and_<B2, B3, Bn...>, B1>::type
{ };