samedi 27 janvier 2018

Recognizing C++ template code patterns

I was reading through a set of some library source files and after reading though the code I can see what it clearly does. That is not the issue. In fact there really isn't any issue, but the more I start to work with templates and read through these documents; some of the patterns are becoming visually recognizable.

The code has this kind of pattern...

template<typename T, typename U, 
    bool is_T_signed = integer_traits<T>::is_signed,
    bool is_U_signed = integer_traits<U>::is_signed>
struct foo_impl {};

template<typename T, typename U>
struct foo_impl<T, U, true, true> {
    static T run( U x ) {
        return ( (x <= /*some max value */ ) && 
                 (x >= /*some min value */ ) );
    }
};

template<typename T, typename U>
struct foo_impl<T, U, false, false> {
    static T run( U x ) {
        return x <= /*some max value*/;
    }
};

template<typename T, typename U>
struct foo_impl<T, U, true, false> {
    static T run( U x ) {
        if ( sizeof( T ) > sizeof( U ) )
            return 1;
        else
            return x <= U( /*some max value*/ );
    }
};

template<typename T, typename U>
struct foo_impl<T, U, false, true> {
    static T run( U x ) {
        if ( sizeof( T ) >= sizeof( U ) )
            return x >= 0;
        else
            return (x >= 0) && (x <= U( /*some max value*/ ));
    }
};

template<typename T, typename U> inline T foo( U x ) {
    return foo_impl<T, U>::run( x );
}


Where it is simply straight forward to understand what the code is intended to do.


  • An empty class template with <T,U,bool = default, bool = default> parameters
  • Specializations of all 4 combinations [t,t], [f,f], [t,f], [f,t].
  • They each return T and accept U as its member function's param and the function is of a static type.
  • These all have impl appended to the end of the struct which refers to the implementation that is abstracted away from the user.
  • Finally a function template that accepts <T,U> params and returns or invokes the struct's internal static method.

What I would like to know for better understanding so that when I begin to see and recognize patterns like this more often I then know what to call them. Is there a preferred common name for this type of pattern? I know that the class or struct is being specialized and invoked in a wrapper function template but this is not what I'm referring to. For example some types of patterns of code are called SFINAE or Tag Dispatching, etc. ... I know that this is probably something simple that I'm overlooking but don't know what to generally call this type of pattern when I see it. I'm not really concerned about the implementation details of the static methods themselves for this concerns the actual overall pattern of the template specialization and then being invoked by a function template wrapper that would be available to the user.

Aucun commentaire:

Enregistrer un commentaire