c++ - check variadic templates parameters for uniqueness -


i want variadic template parameters must unique. know when multi inheritance, identical classes inheritance not allowed.

struct a{}; struct b: a, a{}; // error 

using rule, made little code.

#include <type_traits>  template< class t> struct id{}; template< class ...t> struct base_all : id<t> ... {};  template< class ... t> struct is_unique {      template< class ... u>  static constexpr bool test( base_all<u...> * ) noexcept { return true; }  template< class ... u> static constexpr bool test( ... ) noexcept { return false;}   static constexpr bool value = test<t...>(0); };  int main() {     constexpr bool b = is_unique<int, float, double>::value; // false -- why?     constexpr bool c = is_unique< int, char, int>::value; // false     static_assert( b == true && c == false , "!");// failed. } 

but program not worked expected. what's wrong?

//update: //thanks, fix error: //

//     #include <type_traits> //     #include <cstddef> //     //     template< class ... u> struct pack{}; //     //     template< class t> struct id{}; //     template< class t> struct base_all; //     template< class ... t> struct base_all< pack<t...> > : id<t>  ... {}; //         //      //     //     template< class ... t> //     struct is_unique //     { //           template< class p,  std::size_t  =  sizeof(base_all<p>) > //          struct check; //      //       template< class ...u> //      static constexpr bool test(check< pack<u...> > * ) noexcept { return true;} //         //        template< class ... u> //        static constexpr bool test(...)noexcept { return false;} //         //        static constexpr bool value =  test<t...>(0); //        }; //         //        int main() //        { //            constexpr bool b = is_unique<int, float, double>::value; // true //            constexpr bool c = is_unique< int, char, int>::value; // false //              //          static_assert( b == true && c == false , "!");// success. //        } // 

q: can explain, why it's failed?

update2: previous update illegal :)). legal form, compiled o(n) time.

#include <cstddef> #include <iostream> #include <type_traits>  namespace mpl {  template< class t > using invoke = typename t :: type ;  template< class c, class i, class e > using if_t     = invoke< std::conditional< c{}, i, e> >;  template< class t > struct id{}; struct empty{};  template< class a, class b > struct base : a, b {};  template< class b , class ... > struct is_unique_impl;  template< class b > struct is_unique_impl<b>: std::true_type{};  template< class b, class t, class ... u> struct is_unique_impl<b, t, u...> : if_t< std::is_base_of< id<t>, b>, std::false_type, is_unique_impl< base<b,id<t>>, u...> >{};   template< class ...t >struct is_unique : is_unique_impl< empty, t ... > {};    } // mpl      int main() {     constexpr bool b = mpl::is_unique<int, float, double>::value;      constexpr bool c = mpl::is_unique< int, char, int > :: value;      static_assert( b == true   , "!");     static_assert( c == false, "!");      return 0;  } 

passing pointer base_all<u...> merely requires existence of declaration of base_all<u...>. without attempting access definition, compiler won't detect type ill-defined. 1 approach mitigate problem use argument requires definition of base_all<u...>, e.g.:

template< class ...t> struct base_all    : id<t> ... {     typedef int type; }; // ... template< class ... u> static constexpr bool test(typename base_all<u...>::type) noexcept {     return true; } 

although above answers question, fail compile: multiple inheritance created isn't in suitable context considered sfinae. don't think can leverage rule on not allowing same base inherited twice. relevant test can implemented differently, though:

#include <type_traits>  template <typename...> struct is_one_of;  template <typename f> struct is_one_of<f> {     static constexpr bool value = false; };  template <typename f, typename s, typename... t> struct is_one_of<f, s, t...> {     static constexpr bool value = std::is_same<f, s>::value         || is_one_of<f, t...>::value; };  template <typename...> struct is_unique;  template <> struct is_unique<> {     static constexpr bool value = true; };  template<typename f, typename... t> struct is_unique<f, t...> {     static constexpr bool value = is_unique<t...>::value         && !is_one_of<f, t...>::value; };  int main() {     constexpr bool b = is_unique<int, float, double>::value;     constexpr bool c = is_unique< int, char, int>::value;     static_assert( b == true && c == false , "!"); } 

Comments

Popular posts from this blog

c# - How Configure Devart dotConnect for SQLite Code First? -

java - Copying object fields -

c++ - Clear the memory after returning a vector in a function -