template paramètre de modèle non-type

Dec 07 2020

J'essaie d'écrire une constante constexpr de manière concise en utilisant les fonctionnalités de C ++ 20.

#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);

mais il ne compile ni sur GCC ni clang.

Est-il possible de spécifier des paramètres de modèle sans type de modèle? Il est également possible de l'écrire de manière récursive, mais il serait bon de savoir s'il est possible de l'écrire comme ci-dessus.

Notez que cette question ressemble à modèle modèle paramètre non type , mais le paramètre de modèle non-type est placé dans la liste des paramètres de modèle imbriqué au lieu de la liste des paramètres primaires.

Réponses

2 Kostas Dec 07 2020 at 22:22

Vous ne pouvez pas référencer directement des arguments aux paramètres de modèle de modèle. Ils ne font pas partie de la portée. Mais vous pouvez faire quelque chose comme ceci:

#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
}

Cela étant dit, il existe des moyens plus simples de mettre en œuvre 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
}
4 Mestkon Dec 07 2020 at 22:23

Vous pouvez faire quelque chose comme ceci:

#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);