簡體   English   中英

使用折疊表達式檢查可變參數模板參數是否唯一

[英]Checking if variadic template parameters are unique using fold expressions

給定一個可變參數模板參數包,我想檢查使用inline constexpr boolfold表達式給出的所有類型是否唯一。 我喜歡這樣的東西:

template<class... T>
inline static constexpr bool is_unique = (... && (!is_one_of<T, ...>));

其中is_one_of是一個正常工作的類似bool。 但是無論我將什么放入is_one_of,這一行都無法編譯。 甚至可以使用折疊表達式來完成,還是我需要為此目的使用常規結構?

你的方法並不真正起作用,因為需要使用類型T調用is_one_of ,並且所有其余類型不包括T 沒有辦法用單個參數包上的折疊表達式來表達它。 我建議使用專業化:

template <typename...>
inline constexpr auto is_unique = std::true_type{};

template <typename T, typename... Rest>
inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
    (!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
>{};   

用法:

static_assert(is_unique<>);
static_assert(is_unique<int>);
static_assert(is_unique<int, float, double>);
static_assert(!is_unique<int, float, double, int>);

wandbox.org上的實例


(感謝Barry使用折疊表達式的簡化。)

- 編輯 -

谷歌搜索我發現了一個有趣的解決方案 ,它給了我靈感,以避免遞歸和避免很多警告

所以你可以定義一個類型的包裝器

template <typename>
struct wrapT
 { };

和類型和整數的包裝器,從類型的包裝器繼承

template <typename T, std::size_t>
struct wrapTI : public wrapT<T>
 { };

接下來,您可以定義以遞歸方式wrapTI繼承的foo

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...時間(只有一次) 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> );
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM