15

The following nonsensical example does not compile, but is there some other way to pass a variable template as a template template argument?

template<typename T>
constexpr auto zero = T{0};

template<typename T, template<typename> auto VariableTemplate>
constexpr auto add_one()
{
    return VariableTemplate<T> + T{1};
}

int main()
{
    return add_one<int, zero>();
}

Try on Compiler Explorer

invexed
  • 645
  • 3
  • 10

1 Answers1

6

Short answer: No.

Long answer: Yes you can using some indirection through a class template:

template<typename T>
constexpr auto zero = T{0};

template<typename T>
struct zero_global {
    static constexpr auto value = zero<T>;
};

template<typename T, template<typename> class VariableTemplate>
constexpr auto add_one()
{
    return VariableTemplate<T>::value + T{1};
}

int main()
{
    return add_one<int, zero_global>();
}

Live example

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
  • seems a bit backwards that one has to resort to struct with static member. Is this something one can expect to come with a future standard? Any idea why it isnt possilble already today? – 463035818_is_not_an_ai Oct 28 '19 at 14:24
  • 1
    @formerlyknownas_463035818 I don't think anybody proposed it yet (never saw it in the paper, maybe I missed it?) And there is a complexity too. Right now, non-type template parameter are pr-values. But what would `value` would mean? A reference to the global variable? Also, you can't ODR use non-type template parameter, but you can with a template global. – Guillaume Racicot Oct 28 '19 at 14:32
  • thanks for the hints, I am still on c++11, so I am not too familiar with variable templates, and thats something I would have expected to work out of the box – 463035818_is_not_an_ai Oct 28 '19 at 14:45