Vorlage nicht typen Vorlagenparameter

Dec 07 2020

Ich versuche, eine constexpr-Konstante mit C ++ 20-Funktionen präzise zu schreiben.

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

aber es wird weder auf GCC kompiliert noch geklirrt.

Ist es möglich, Vorlagenparameter anzugeben, die nicht vom Typ sind? Alternativ ist es möglich, es rekursiv zu schreiben, aber es wäre schön zu wissen, ob es möglich ist, es wie oben zu schreiben.

Beachten Sie, dass diese Frage dem Nicht-Typ-Parameter der Vorlagenvorlage ähnelt, der Nicht-Typ-Vorlagenparameter jedoch nicht in der primären Parameterliste, sondern in der Liste der verschachtelten Vorlagenparameter platziert wird.

Antworten

2 Kostas Dec 07 2020 at 22:22

Sie können Argumente nicht direkt auf Vorlagenvorlagenparameter verweisen. Sie sind nicht im Geltungsbereich. Aber Sie könnten so etwas tun:

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

Davon abgesehen gibt es einfachere Möglichkeiten zur Implementierung 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

Sie könnten so etwas tun:

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