szablon parametr szablonu innego niż typ
Próbuję napisać stałą constexpr zwięźle przy użyciu funkcji 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);
ale nie kompiluje się ani na GCC, ani na clang.
Czy można określić parametry szablonu innego niż typ? Alternatywnie można to zapisać rekurencyjnie, ale dobrze byłoby wiedzieć, czy można to zapisać tak jak powyżej.
Zauważ, że to pytanie wygląda podobnie do parametru innego niż typ szablonu szablonu, ale parametr szablonu innego niż typ jest umieszczany na zagnieżdżonej liście parametrów szablonu zamiast na liście parametrów podstawowych.
Odpowiedzi
Nie można bezpośrednio odwoływać się do argumentów do parametrów szablonu. Nie ma ich w zakresie. Ale możesz zrobić coś takiego:
#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
}
Biorąc to pod uwagę, istnieją prostsze sposoby implementacji 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
}
Możesz zrobić coś takiego:
#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);