简体   繁体   中英

template non-type template parameter

I am trying to write a constexpr constant concisely using C++20 features.

#include <utility>

template <template <typename T, T ... Ints> std::integer_sequence<T, Ints...> I>
static constexpr long pow10_helper = ((Ints, 10) * ...);

template <std::size_t exp>
static constexpr long pow10 = pow10_helper< std::make_index_sequence<exp> >;

static_assert(pow10<3> == 1000);

but it is not compiling neither on GCC nor clang.

Is it possible to specify template non-type template parameters? Alternatively it is possible to write it recursively, but it would be nice to know if it is possible to write it like above.

Note that this question looks similar to Template template non-type parameter but the non-type template parameter is placed in the nested template parameter list instead of on the primary parameter list.

You could do something like this:

#include <utility>

template<class T>
static constexpr long pow10_helper;

template<class T, T... Is>
static constexpr long pow10_helper<std::integer_sequence<T, Is...>> = ((Is, 10) * ...);

template <std::size_t exp>
static constexpr long pow10 = pow10_helper<std::make_index_sequence<exp> >;

static_assert(pow10<3> == 1000);

You cannot directly reference arguments to template template parameters. They are not in scope. But you could do something like this:

#include <utility>

template <class>
class pow10_helper {};

template <template <typename T, T ...> class IntSeq, class T, T ... Ints>
struct pow10_helper<IntSeq<T, Ints...>> {
  static constexpr long value = ((Ints, 10) * ...);
};

template <size_t pow>
static constexpr long pow10 = pow10_helper<std::make_index_sequence<pow>>::value;
#include <iostream>
int main() {
  size_t pow = pow10<3>;
  std::cout << pow << std::endl; // prints 1000
}

That being said, there are simpler ways of implementing pow10 :

template <size_t pow>
struct pow10 { static constexpr size_t value = 10 * pow10<pow-1>::value; };
template <> struct pow10<0> { static constexpr size_t value = 1; };
int main() {
  size_t pow = pow10<3>::value;
  std::cout << pow << std::endl; //prints 1000
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM