home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 31,358 of 33,346   
   Marc to All   
   Re: arrays decaying to pointers   
   31 May 11 13:28:43   
   
   From: marc.glisse@gmail.com   
      
   Daniel Krügler  wrote:   
      
   > On 2011-05-30 14:56, Marc wrote:   
   >>   
   >> Hello,   
   >>   
   >> arrays decay to pointers, which allows for:   
   >>   
   >> template   
   >> void f(Iter first, Iter theend);   
   >>   
   >> int tab[]={1,2,3};   
   >> f(tab,tab+3);   
   >>   
   >> and Iter is deduced as int*.   
   >>   
   >> However, if I go through a forwarding function:   
   >> template   
   >> void g(A const&a, B const&b){ f(a,b); }   
   >> g(tab,tab+3);   
   >>   
   >> f now receives a reference to an array of _const_ int and a reference   
   >> to a const pointer to int. But just passing f a pointer to const   
   >> int and a pointer to int is already an error as the compiler can't   
   >> deduce Iter anymore (yes, one could dream about a compiler clever   
   >> enough to deduce Iter as const int* in this case).   
   >>   
   >> So it looks like my best bet is to define f with 2 different template   
   >> parameters:   
   >> template   
   >> void f(Iter1 first, Iter2 theend);   
   >>   
   >> and possibly add various checks to make sure Iter1 and Iter2 are   
   >> compatible. Is there some better way?   
   >   
   > I would stay away from adding several overloads. Instead I would follow   
   the spirit of make_tuple as described in TR1 (modulo reference_wrapper   
   unwrapping but plus decaying): The function template takes arguments by   
   const& Ti, but would convert them to std::decay::type. This requires   
   that you can create a helper function like   
   >   
   > template    
   > typename decay::type decay_copy(const T& v)   
   > { return v; }   
   >   
   > with C++03 means. IMO this should not be too hard to realize (Implementing   
   the decay trait should be possible with C++03 means). The advantage over   
   using begin/end is that this decay-forwarder can be used for other decayable   
   types. The final call syntax would then be:   
   >   
   > void g(A const&a, B const&b){ f(decay_copy(a), decay_copy(b)); }   
      
   I hadn't looked at make_tuple yet, thanks for the pointer.   
      
   I had thought about something similar, except that I saw it more like a   
   std::forward with an exception for arrays. But it looks like I will still   
   hit the issue that decay_copy(a) is _const_ int* whereas decay_copy(b) is   
   int*. And that's hard to solve without either sticking a const below every   
   pointer or making 2^n overloads of the forwarding function.   
      
   The startOf/EndOf suggested in the other answer is really just a   
   reimplementation of the C++0X begin/end.   
      
   I guess I'll just document that passing arrays instead of pointers is   
   forbidden (at least in C++03).   
      
      
   --   
         [ 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)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca