- 编辑 -
谷歌搜索我找到了一个有趣的解决方案,它给了我灵感来避免递归并避免很多警告
所以你可以定义一个类型的包装器
template <typename>
struct wrapT
{ };
以及从类型包装器继承的类型和整数包装器
template <typename T, std::size_t>
struct wrapTI : public wrapT<T>
{ };
接下来,您可以定义一个递归继承自的foo
类wrapTI
template <typename T,
typename = std::make_index_sequence<std::tuple_size<T>::value>>
struct foo;
template <typename ... Ts, std::size_t ... Is>
struct foo<std::tuple<Ts...>, std::index_sequence<Is...>>
: public wrapTI<Ts, Is>...
{ };
现在is_unique
可以像
template <typename ... Ts>
static constexpr bool isUnique
= ( ... && std::is_convertible<foo<std::tuple<Ts...>>, wrapT<Ts>>::value );
关键是只有从 继承一次(并且只有一次)foo<Ts...>
才能转换为,也就是说,如果在 中存在一次(并且只有一次)。wrapT<T>
foo<Ts...>
wrapT<T>
T
Ts...
下面是一个完整的编译示例
#include <tuple>
#include <type_traits>
template <typename>
struct wrapT
{ };
template <typename T, std::size_t>
struct wrapTI : public wrapT<T>
{ };
template <typename T,
typename = std::make_index_sequence<std::tuple_size<T>::value>>
struct foo;
template <typename ... Ts, std::size_t ... Is>
struct foo<std::tuple<Ts...>, std::index_sequence<Is...>>
: public wrapTI<Ts, Is>...
{ };
template <typename ... Ts>
static constexpr bool isUnique
= ( ... && std::is_convertible<foo<std::tuple<Ts...>>, wrapT<Ts>>::value );
int main ()
{
static_assert( true == isUnique<int, long, long long> );
static_assert( false == isUnique<int, long, long long, int> );
}