template parametro template non di tipo

Dec 07 2020

Sto cercando di scrivere una costante constexpr in modo conciso utilizzando le funzionalità di 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);

ma non sta compilando né su GCC né clang.

È possibile specificare parametri di template non di tipo template? In alternativa è possibile scriverlo ricorsivamente, ma sarebbe bello sapere se è possibile scriverlo come sopra.

Si noti che questa domanda è simile al parametro del modello non di tipo modello, ma il parametro del modello non di tipo viene inserito nell'elenco dei parametri del modello nidificato anziché nell'elenco dei parametri principali.

Risposte

2 Kostas Dec 07 2020 at 22:22

Non è possibile fare riferimento diretto agli argomenti ai parametri del modello del modello. Non sono nel campo di applicazione. Ma potresti fare qualcosa del genere:

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

Detto questo, ci sono modi più semplici per implementare 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

Potresti fare qualcosa del genere:

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