Alias template specialisation

后端 未结 4 1421

Can alias templates (14.5.7) be explicitly specialised (14.7.3)?

My standard-fu fails me, and I can\'t find a compiler to test on.

The text \"when a template

4条回答
  •  难免孤独
    2020-11-27 18:02

    I am not sure if I understand the question, but in any case I tried to simulate specialization of alias template.

    I assume that the idea is to restrict the alias template to certain (pattern matched type); something that we used to do with this sort of code:

    template struct old_style;
    template struct old_style >{
       typedef typename std::vector::value_type type;
    };
    

    (this is just an example, there are other way to extract the value_type of a generic std::vector).

    Now to the aliases:

    template using new_style = typename Vector::value_type;
    

    It does the same work, but this does not replace old_stype<...>::type, since it is not as restrictive. The first try to have a perfect alias replacement is this hypothetical code:

    //template using new_style2; // error already here
    //template using new_style2 > = typename Vector::value_type;
    

    Unfortunately it doesn't compile (in theory because of nominal reasons stated in other answers and in the standard, in practice I guess there is no fundamental reason for this to be a limitation). Fortunately one can fallback to the old fashioned struct::type way of doing it an only use the new alias template feature to forward the work,

    template struct new_style2_aux;
    template struct new_style2_aux >{
       typedef typename std::vector::value_type type;
    };
    template using new_style2 = typename new_style2_aux::type;
    

    One can make it automatic with a define

    #define SPECIALIZED_ALIAS_TEMPLATE(NamE, Pattern_arG, PatterN_expR, DefinitioN) \
    template struct NamE ## _aux; \
    template struct NamE ## _aux{ \
        typedef DefinitioN type; \
    }; \
    template using NamE = typename NamE ## _aux< NamE ## _dummy >::type; 
    

    Which can be used as:

    SPECIALIZED_ALIAS_TEMPLATE(new_style3, class T, std::vector, typename std::vector::value_type);
    

    If one needs an arbitrary number of specializations (or non local in the code), one has to use a more complicated define in two parts, one for declaring and one for specializing (as it should be):

    #define DECLARE_ALIAS_TEMPLATE(NamE)\
    template struct NamE ## _aux;\
    template using NamE = typename NamE ## _aux< NamE ## _dummy >::type; 
    
    #define SPECIALIZE_ALIAS_TEMPLATE(NamE, Pattern_arG, PatterN_expR, DefinitioN)\
    template struct NamE ## _aux{ \
        typedef DefinitioN type; \
    };
    

    Used as follows:

    DECLARE_ALIAS_TEMPLATE(new_style4);
    
    SPECIALIZE_ALIAS_TEMPLATE(new_style4, class T, std::vector, typename std::vector::value_type);
    SPECIALIZE_ALIAS_TEMPLATE(new_style4, class T, std::set, typename std::set::value_type);
    

    All the code above can be copied and pasted to test:

    #include
    #include
    // ... paste code above //
    int main(){
        old_style >::type a; // is a double
    //  old_style >::type a; // error (should work only for std::vector)
        new_style2 > b; // is double
    //  new_style2 > c; // error (should work only for std::vector)
        new_style3 > d; // is double
    //  new_style3 > d; // error (should work only for std::vector)
        new_style4 > e; // is double
        new_style4 > f; // is double, this is another specialization
        return 0;
    }
    

    Sorry if this is not what you are looking for. I believe it can be used with variadic templates, and with extra template arguments (in the specialization) but didn't test it.

    Improvements are very welcomed.

提交回复
热议问题