SFINAE compiler troubles

前端 未结 5 931
一向
一向 2021-02-06 08:54

The following code of mine should detect whether T has begin and end methods:

template 
struct is_contai         


        
5条回答
  •  半阙折子戏
    2021-02-06 09:32

    Why are you going to all that effort? If you want to check if U::begin() exists, why not try it?

    template 
    struct is_container
    {
        template  static char test(U* u,
           typename U::const_iterator b = ((U*)0)->begin(),
           typename U::const_iterator e = ((U*)0)->end());
        template  static long test(...);
    
        enum { value = (1 == sizeof test(0)) };
    };
    

    In addition to checking for the existance of U::begin() and U::end(), this also checks whether they return something that is convertible to a const_iterator. It also avoids the pitfall highlighted by Stephan T. Lavavej by using a call expression that must be supported, instead of assuming a particular signature.

    [edit] Sorry, this relied on VC10's template instantiation. Better approach (puts the existance check in the argument types, which do participate in overloading):

    template  struct is_container
    {
        // Is.
        template 
        static char test(U* u, 
                         int (*b)[sizeof(typename U::const_iterator()==((U*)0)->begin())] = 0,
                         int (*e)[sizeof(typename U::const_iterator()==((U*)0)->end())] = 0);
        // Is not.
        template  static long test(...);
    
        enum { value = (1 == sizeof test(0)) };
    };
    

提交回复
热议问题