From: daniel.kruegler@googlemail.com   
      
   On 2013-08-02 09:53, Daryle Walker wrote:   
   > I think that std::tuple has a constructor like:   
   >   
   > template < typename ...Types >   
   > struct tuple   
   > {   
   > //...   
   >   
   > // Only valid when sizeof...(Types) == 2   
   > template < typename T, typename U >   
   > tuple( std::pair p );   
   >   
   > //...   
   > };   
   >   
   > Is there a way to implement that besides having it in a (partial)   
   > specialization when there are two parameters and omitting it for all   
   > other specializations?   
      
   This is indeed very easily possible (and I don't think that there exist   
   a real std::tuple implementation in the wild which would use partial   
   specialization).   
      
   > I'm thinking about adding constructors like   
   > these in a class template of mine, but I don't want to write a bunch of   
   > otherwise-identical specializations.   
      
   If you only want to impose constraint upon the size, this can be solved   
   like this:   
      
    template ::value == 2,   
   bool>::type = false   
    >   
    my_tuple(const std::pair&);   
      
   I'm assuming here that std::tuple_size is specialized for your type   
   my_tuple. If not, replace std::tuple_size by a type-dependent template   
   such as   
      
   template   
   constexpr std::size_t pack_size()   
   {   
    return sizeof...(Args);   
   }   
      
   and write it like this:   
      
    template () == 2, bool>::type = false   
    >   
    my_tuple(const std::pair&);   
      
   (The introduction of either std::tuple_size or pack_size() ensures that   
   the sfinae test condition is type-dependent, which is currently needed)   
      
   If you want to impose further constraints that should be imposed   
   element-wise, there is no need for the extra-constraint upon sizes, it   
   can often be done implicitly. Consider the following example given the   
   following utility templates (useful elsewhere as well)   
      
   template::value>   
   struct nth_type_impl   
   {   
    typedef typename std::tuple_element::type type;   
   };   
      
   template   
   struct nth_type_impl   
   {   
    typedef void type;   
   };   
      
   template   
   using nth_type = typename nth_type_impl>::type;   
      
   template   
   struct and_;   
      
   template<>   
   struct and_<> : std::true_type {};   
      
   template   
   struct and_ : P {};   
      
   template   
   struct and_ : std::conditional::type {};   
      
   template   
   struct and_ : std::conditional, P1>::type {};   
      
   Now you can for example impose the following constraints:   
      
    template >,   
    std::is_convertible>   
    >::value   
    , bool>::type = false   
    >   
    my_tuple(const std::pair&);   
      
   Depending on your exact use-case even simpler ways exist.   
      
   HTH & GReetings from Bremen,   
      
   Daniel Krügler   
      
      
   --   
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
    [ comp.lang.c++.moderated. First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|