template parameter template non-jenis
Saya mencoba menulis konstanta constexpr secara ringkas menggunakan fitur 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);
tetapi tidak dapat dikompilasi di GCC maupun dentang.
Apakah mungkin untuk menentukan parameter template non-type template? Alternatifnya adalah mungkin untuk menulisnya secara rekursif, tetapi alangkah baiknya mengetahui apakah mungkin untuk menulisnya seperti di atas.
Perhatikan bahwa pertanyaan ini terlihat mirip dengan parameter non-jenis template Template tetapi parameter template non-jenis ditempatkan di daftar parameter template bertingkat, bukan di daftar parameter utama.
Jawaban
Anda tidak bisa secara langsung mereferensikan argumen ke parameter template template. Mereka tidak berada dalam jangkauan. Tapi Anda bisa melakukan sesuatu seperti ini:
#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
}
Karena itu, ada cara penerapan yang lebih sederhana 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
}
Anda bisa melakukan sesuatu seperti ini:
#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);