Checking if variadic template parameters are unique using fold expressions












6














Given a variadic template parameter pack, I want to check if all types given to it are unique using an inline constexpr bool and fold expressions. I trie something like this:



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


Where is_one_of is a similar bool that works correctly.
But this line doesn't compile regardless of what I put into is_one_of. Can this even be done using fold expressions, or do I need to use a regular struct for this purpose?










share|improve this question





























    6














    Given a variadic template parameter pack, I want to check if all types given to it are unique using an inline constexpr bool and fold expressions. I trie something like this:



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


    Where is_one_of is a similar bool that works correctly.
    But this line doesn't compile regardless of what I put into is_one_of. Can this even be done using fold expressions, or do I need to use a regular struct for this purpose?










    share|improve this question



























      6












      6








      6


      2





      Given a variadic template parameter pack, I want to check if all types given to it are unique using an inline constexpr bool and fold expressions. I trie something like this:



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


      Where is_one_of is a similar bool that works correctly.
      But this line doesn't compile regardless of what I put into is_one_of. Can this even be done using fold expressions, or do I need to use a regular struct for this purpose?










      share|improve this question















      Given a variadic template parameter pack, I want to check if all types given to it are unique using an inline constexpr bool and fold expressions. I trie something like this:



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


      Where is_one_of is a similar bool that works correctly.
      But this line doesn't compile regardless of what I put into is_one_of. Can this even be done using fold expressions, or do I need to use a regular struct for this purpose?







      c++ templates c++17 variadic-templates fold-expression






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 21 '18 at 13:56









      max66

      34.5k63762




      34.5k63762










      asked Nov 27 '17 at 12:50









      Joald

      391216




      391216
























          2 Answers
          2






          active

          oldest

          votes


















          9














          You approach doesn't really work because is_one_of needs to be called with a type T and all the remaining types not including T. There's no way of expressing that with a fold expression over a single parameter pack. I suggest using specialization instead:



          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...>
          >{};


          Usage:



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


          live example on wandbox.org





          (Thanks to Barry for the simplification that uses a fold expression.)






          share|improve this answer























          • You're right. I trusted my YouCompleteMe config too much, which surprisingly gave me diags even though it didn't even grok all the c++17 features. Disregard. I'll have to wrap my head around why it works, though because I suspected the given case to fail, from brain-compiling it. Got it; My brain-compiler failed to see T1, Rest... as "just the tail", which it of course is. +1
            – sehe
            Nov 27 '17 at 13:05








          • 3




            Could simplify to T0, Rest... with the body of (!is_same_v<T0, Rest> && ...) && is_unique<Rest...>?
            – Barry
            Nov 27 '17 at 16:27






          • 2




            While the other answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so your answer "You can't do it" is more appropriate. Thanks!
            – Joald
            Nov 27 '17 at 19:21





















          1














          -- EDIT --



          googling I've found an interesting solution that give me inspiration to avoid recursion and to avoid a lot of warnings



          So you can define a wrapper of type



          template <typename>
          struct wrapT
          { };


          and a wrapper for type and integer that inherit from the wrapper for type



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


          Next you can define a foo class that recursively inherit from 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>...
          { };


          Now is_unique can be something like



          template <typename ... Ts>
          static constexpr bool isUnique
          = ( ... && std::is_convertible<foo<std::tuple<Ts...>>, wrapT<Ts>>::value );


          The point is that foo<Ts...> can be converted to wrapT<T> only if foo<Ts...> inherit one time (and only one time) from wrapT<T>, that is if T is present one time (and only one time) in Ts....



          The following is a full compiling example



          #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> );
          }





          share|improve this answer























          • While your answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so the other answer "You can't do it" is more appropriate. But thanks, cool to know that it can be done!
            – Joald
            Nov 27 '17 at 19:22










          • @Joald - I'm agree with you: the Vittorio's answer is better than mine (and also I find annoying those warnings)
            – max66
            Nov 27 '17 at 21:08










          • @Joald - Just for fun... answer modified, recursion avoided and warnings removed :) - But added another wrapper struct :(
            – max66
            Nov 27 '17 at 22:12











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47511415%2fchecking-if-variadic-template-parameters-are-unique-using-fold-expressions%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          9














          You approach doesn't really work because is_one_of needs to be called with a type T and all the remaining types not including T. There's no way of expressing that with a fold expression over a single parameter pack. I suggest using specialization instead:



          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...>
          >{};


          Usage:



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


          live example on wandbox.org





          (Thanks to Barry for the simplification that uses a fold expression.)






          share|improve this answer























          • You're right. I trusted my YouCompleteMe config too much, which surprisingly gave me diags even though it didn't even grok all the c++17 features. Disregard. I'll have to wrap my head around why it works, though because I suspected the given case to fail, from brain-compiling it. Got it; My brain-compiler failed to see T1, Rest... as "just the tail", which it of course is. +1
            – sehe
            Nov 27 '17 at 13:05








          • 3




            Could simplify to T0, Rest... with the body of (!is_same_v<T0, Rest> && ...) && is_unique<Rest...>?
            – Barry
            Nov 27 '17 at 16:27






          • 2




            While the other answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so your answer "You can't do it" is more appropriate. Thanks!
            – Joald
            Nov 27 '17 at 19:21


















          9














          You approach doesn't really work because is_one_of needs to be called with a type T and all the remaining types not including T. There's no way of expressing that with a fold expression over a single parameter pack. I suggest using specialization instead:



          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...>
          >{};


          Usage:



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


          live example on wandbox.org





          (Thanks to Barry for the simplification that uses a fold expression.)






          share|improve this answer























          • You're right. I trusted my YouCompleteMe config too much, which surprisingly gave me diags even though it didn't even grok all the c++17 features. Disregard. I'll have to wrap my head around why it works, though because I suspected the given case to fail, from brain-compiling it. Got it; My brain-compiler failed to see T1, Rest... as "just the tail", which it of course is. +1
            – sehe
            Nov 27 '17 at 13:05








          • 3




            Could simplify to T0, Rest... with the body of (!is_same_v<T0, Rest> && ...) && is_unique<Rest...>?
            – Barry
            Nov 27 '17 at 16:27






          • 2




            While the other answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so your answer "You can't do it" is more appropriate. Thanks!
            – Joald
            Nov 27 '17 at 19:21
















          9












          9








          9






          You approach doesn't really work because is_one_of needs to be called with a type T and all the remaining types not including T. There's no way of expressing that with a fold expression over a single parameter pack. I suggest using specialization instead:



          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...>
          >{};


          Usage:



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


          live example on wandbox.org





          (Thanks to Barry for the simplification that uses a fold expression.)






          share|improve this answer














          You approach doesn't really work because is_one_of needs to be called with a type T and all the remaining types not including T. There's no way of expressing that with a fold expression over a single parameter pack. I suggest using specialization instead:



          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...>
          >{};


          Usage:



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


          live example on wandbox.org





          (Thanks to Barry for the simplification that uses a fold expression.)







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 27 '17 at 22:51

























          answered Nov 27 '17 at 12:56









          Vittorio Romeo

          57.4k17154293




          57.4k17154293












          • You're right. I trusted my YouCompleteMe config too much, which surprisingly gave me diags even though it didn't even grok all the c++17 features. Disregard. I'll have to wrap my head around why it works, though because I suspected the given case to fail, from brain-compiling it. Got it; My brain-compiler failed to see T1, Rest... as "just the tail", which it of course is. +1
            – sehe
            Nov 27 '17 at 13:05








          • 3




            Could simplify to T0, Rest... with the body of (!is_same_v<T0, Rest> && ...) && is_unique<Rest...>?
            – Barry
            Nov 27 '17 at 16:27






          • 2




            While the other answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so your answer "You can't do it" is more appropriate. Thanks!
            – Joald
            Nov 27 '17 at 19:21




















          • You're right. I trusted my YouCompleteMe config too much, which surprisingly gave me diags even though it didn't even grok all the c++17 features. Disregard. I'll have to wrap my head around why it works, though because I suspected the given case to fail, from brain-compiling it. Got it; My brain-compiler failed to see T1, Rest... as "just the tail", which it of course is. +1
            – sehe
            Nov 27 '17 at 13:05








          • 3




            Could simplify to T0, Rest... with the body of (!is_same_v<T0, Rest> && ...) && is_unique<Rest...>?
            – Barry
            Nov 27 '17 at 16:27






          • 2




            While the other answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so your answer "You can't do it" is more appropriate. Thanks!
            – Joald
            Nov 27 '17 at 19:21


















          You're right. I trusted my YouCompleteMe config too much, which surprisingly gave me diags even though it didn't even grok all the c++17 features. Disregard. I'll have to wrap my head around why it works, though because I suspected the given case to fail, from brain-compiling it. Got it; My brain-compiler failed to see T1, Rest... as "just the tail", which it of course is. +1
          – sehe
          Nov 27 '17 at 13:05






          You're right. I trusted my YouCompleteMe config too much, which surprisingly gave me diags even though it didn't even grok all the c++17 features. Disregard. I'll have to wrap my head around why it works, though because I suspected the given case to fail, from brain-compiling it. Got it; My brain-compiler failed to see T1, Rest... as "just the tail", which it of course is. +1
          – sehe
          Nov 27 '17 at 13:05






          3




          3




          Could simplify to T0, Rest... with the body of (!is_same_v<T0, Rest> && ...) && is_unique<Rest...>?
          – Barry
          Nov 27 '17 at 16:27




          Could simplify to T0, Rest... with the body of (!is_same_v<T0, Rest> && ...) && is_unique<Rest...>?
          – Barry
          Nov 27 '17 at 16:27




          2




          2




          While the other answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so your answer "You can't do it" is more appropriate. Thanks!
          – Joald
          Nov 27 '17 at 19:21






          While the other answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so your answer "You can't do it" is more appropriate. Thanks!
          – Joald
          Nov 27 '17 at 19:21















          1














          -- EDIT --



          googling I've found an interesting solution that give me inspiration to avoid recursion and to avoid a lot of warnings



          So you can define a wrapper of type



          template <typename>
          struct wrapT
          { };


          and a wrapper for type and integer that inherit from the wrapper for type



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


          Next you can define a foo class that recursively inherit from 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>...
          { };


          Now is_unique can be something like



          template <typename ... Ts>
          static constexpr bool isUnique
          = ( ... && std::is_convertible<foo<std::tuple<Ts...>>, wrapT<Ts>>::value );


          The point is that foo<Ts...> can be converted to wrapT<T> only if foo<Ts...> inherit one time (and only one time) from wrapT<T>, that is if T is present one time (and only one time) in Ts....



          The following is a full compiling example



          #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> );
          }





          share|improve this answer























          • While your answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so the other answer "You can't do it" is more appropriate. But thanks, cool to know that it can be done!
            – Joald
            Nov 27 '17 at 19:22










          • @Joald - I'm agree with you: the Vittorio's answer is better than mine (and also I find annoying those warnings)
            – max66
            Nov 27 '17 at 21:08










          • @Joald - Just for fun... answer modified, recursion avoided and warnings removed :) - But added another wrapper struct :(
            – max66
            Nov 27 '17 at 22:12
















          1














          -- EDIT --



          googling I've found an interesting solution that give me inspiration to avoid recursion and to avoid a lot of warnings



          So you can define a wrapper of type



          template <typename>
          struct wrapT
          { };


          and a wrapper for type and integer that inherit from the wrapper for type



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


          Next you can define a foo class that recursively inherit from 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>...
          { };


          Now is_unique can be something like



          template <typename ... Ts>
          static constexpr bool isUnique
          = ( ... && std::is_convertible<foo<std::tuple<Ts...>>, wrapT<Ts>>::value );


          The point is that foo<Ts...> can be converted to wrapT<T> only if foo<Ts...> inherit one time (and only one time) from wrapT<T>, that is if T is present one time (and only one time) in Ts....



          The following is a full compiling example



          #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> );
          }





          share|improve this answer























          • While your answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so the other answer "You can't do it" is more appropriate. But thanks, cool to know that it can be done!
            – Joald
            Nov 27 '17 at 19:22










          • @Joald - I'm agree with you: the Vittorio's answer is better than mine (and also I find annoying those warnings)
            – max66
            Nov 27 '17 at 21:08










          • @Joald - Just for fun... answer modified, recursion avoided and warnings removed :) - But added another wrapper struct :(
            – max66
            Nov 27 '17 at 22:12














          1












          1








          1






          -- EDIT --



          googling I've found an interesting solution that give me inspiration to avoid recursion and to avoid a lot of warnings



          So you can define a wrapper of type



          template <typename>
          struct wrapT
          { };


          and a wrapper for type and integer that inherit from the wrapper for type



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


          Next you can define a foo class that recursively inherit from 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>...
          { };


          Now is_unique can be something like



          template <typename ... Ts>
          static constexpr bool isUnique
          = ( ... && std::is_convertible<foo<std::tuple<Ts...>>, wrapT<Ts>>::value );


          The point is that foo<Ts...> can be converted to wrapT<T> only if foo<Ts...> inherit one time (and only one time) from wrapT<T>, that is if T is present one time (and only one time) in Ts....



          The following is a full compiling example



          #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> );
          }





          share|improve this answer














          -- EDIT --



          googling I've found an interesting solution that give me inspiration to avoid recursion and to avoid a lot of warnings



          So you can define a wrapper of type



          template <typename>
          struct wrapT
          { };


          and a wrapper for type and integer that inherit from the wrapper for type



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


          Next you can define a foo class that recursively inherit from 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>...
          { };


          Now is_unique can be something like



          template <typename ... Ts>
          static constexpr bool isUnique
          = ( ... && std::is_convertible<foo<std::tuple<Ts...>>, wrapT<Ts>>::value );


          The point is that foo<Ts...> can be converted to wrapT<T> only if foo<Ts...> inherit one time (and only one time) from wrapT<T>, that is if T is present one time (and only one time) in Ts....



          The following is a full compiling example



          #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> );
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 27 '17 at 22:10

























          answered Nov 27 '17 at 14:23









          max66

          34.5k63762




          34.5k63762












          • While your answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so the other answer "You can't do it" is more appropriate. But thanks, cool to know that it can be done!
            – Joald
            Nov 27 '17 at 19:22










          • @Joald - I'm agree with you: the Vittorio's answer is better than mine (and also I find annoying those warnings)
            – max66
            Nov 27 '17 at 21:08










          • @Joald - Just for fun... answer modified, recursion avoided and warnings removed :) - But added another wrapper struct :(
            – max66
            Nov 27 '17 at 22:12


















          • While your answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so the other answer "You can't do it" is more appropriate. But thanks, cool to know that it can be done!
            – Joald
            Nov 27 '17 at 19:22










          • @Joald - I'm agree with you: the Vittorio's answer is better than mine (and also I find annoying those warnings)
            – max66
            Nov 27 '17 at 21:08










          • @Joald - Just for fun... answer modified, recursion avoided and warnings removed :) - But added another wrapper struct :(
            – max66
            Nov 27 '17 at 22:12
















          While your answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so the other answer "You can't do it" is more appropriate. But thanks, cool to know that it can be done!
          – Joald
          Nov 27 '17 at 19:22




          While your answer provides a way to do that with fold expression and constexpr bool as I wanted, it comes with a lot of warnings and still requires additional structs which I wanted to do without, so the other answer "You can't do it" is more appropriate. But thanks, cool to know that it can be done!
          – Joald
          Nov 27 '17 at 19:22












          @Joald - I'm agree with you: the Vittorio's answer is better than mine (and also I find annoying those warnings)
          – max66
          Nov 27 '17 at 21:08




          @Joald - I'm agree with you: the Vittorio's answer is better than mine (and also I find annoying those warnings)
          – max66
          Nov 27 '17 at 21:08












          @Joald - Just for fun... answer modified, recursion avoided and warnings removed :) - But added another wrapper struct :(
          – max66
          Nov 27 '17 at 22:12




          @Joald - Just for fun... answer modified, recursion avoided and warnings removed :) - But added another wrapper struct :(
          – max66
          Nov 27 '17 at 22:12


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47511415%2fchecking-if-variadic-template-parameters-are-unique-using-fold-expressions%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          TypeError: fit_transform() missing 1 required positional argument: 'X'