Search code examples
c++c++20template-templates

Is there a workaround for template template arguments being invisible?


Consider the following code:

template<typename... Args1> 
constexpr size_t direct = sizeof... (Args1);

template<template<typename... Args1> typename A1> 
constexpr size_t nested = sizeof... (Args1); // compile error ☹️

Nested line does not compile since (I presume) Args1 is a nested argument.

Is there a way to work around this in a non-intrusive way? By intrusive I mean modifying types passed, for example adding

constexpr size_t sizeof_args = sizeof... (Args...);

to each template passed to this template.

Note: I am fine with using C++20 concepts, but AFAIK they do not offer improvements in this space.


Solution

  • You can write a primary variable template, and then specialize the variable template for template template parameters.

    This allows you to explicitly name the template parameters of the template template parameter separately:

    template<typename ...> 
    constexpr size_t nested = -1; // any value will do, 
                                  // but prefer one that is invalid for specializations
    
    template<template<typename ...> typename A1, typename... Args1> 
                    // name the parameters here  ^_______________^
    constexpr size_t nested<A1<Args1...>> = sizeof...(Args1);
        // specialize here ^____________^
    

    The concepts feature added in C++20 doesn't help in any way here, since there's nothing being constrained.

    Here's a demo.