From: daniel.kruegler@googlemail.com   
      
   On 2011-05-25 02:28, Brendan Miller wrote:   
   > I have these two template functions and a related utility type:   
   >   
   > template    
   > struct second_type {   
   > typedef T type;   
   > };   
   >   
   > template    
   > bool is_back_insertion_seq() {   
   > return false;   
   > }   
   >   
   >   
   > // Using SFINAE to disable this function for non-back-insertion   
   > // sequences.   
   > template    
   > typename second_type<   
   > decltype(T().push_back(   
   > typename iterator_traits T().begin())>::value_type())),   
   > bool>::type   
   > is_back_insertion_seq() {   
   > return true;   
   > }   
   >   
   > If I call is_back_insertion_seq >() I want the second form   
   > to be called.   
   >   
   > However, actually when I call is_back_insertion_seq >(), the   
   > compiler errors out, as the call is ambiguous.   
   >   
   > Is there a trick to make one overload preferable to the other if the two   
   > are ambiguous?   
      
   Sure. One way to realize that is to add different function parameters   
   and a call expression with some argument such that one overload would be   
   preferred. Here is an example that uses this technique:   
      
   #include    
   #include    
      
   template   
   struct is_back_insertion_seq_trait_impl   
   {   
    template::value_type()))   
    >   
    static std::true_type test(int);   
      
    template   
    static std::false_type test(...);   
      
    typedef decltype(is_back_insertion_seq_trait_impl::test(0)) type;   
   };   
      
   template   
   struct is_back_insertion_seq_trait :   
    is_back_insertion_seq_trait_impl::type   
   {   
   };   
      
   template    
   typename std::enable_if::value, bool>::type   
   is_back_insertion_seq() {   
    return false;   
   }   
      
   template    
   typename std::enable_if::value, bool>::type   
   is_back_insertion_seq() {   
    return true;   
   }   
      
   You may notice that within is_back_insertion_seq_trait_impl the two test   
   functions are provided. The second overload is less preferred compared   
   to the second one in overload resolution. Technically this is so,   
   because a standard conversion sequence is a better conversion sequence   
   than an ellipsis conversion sequence ([over.ics.rank]).   
      
   Let me add that I suggest to use std::declval instead of   
   value-initialization in your decltype usage, because there does not   
   exist a fundamental requirement, that a back insertion sequence is   
   default-constructible.   
      
   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)   
|