[英]c++ numerical parser using template metaprogramming
我已經嘗試了大約4個小時,試圖找到一種方法來編譯此代碼:
template < char ... RHS, unsigned int i>
struct t {
static const char s[] = t<' ', char(i+'0'), RHS, i-1>::s;
};
template <char ... RHS >
struct t<RHS, 0> {
static const char s[] = {'0', RHS, '\0'};
};
void main() {
std::cout << t<5>::s; // {'0',' ','1',' ','2',' ','3',' ','4',' ','5','\0'}
}
我從另一篇文章中得知,我沒有鏈接,但是這段代碼試圖在編譯時將一個數字解析為char。 任何幫助為什么此代碼無法編譯? 提前謝謝!
#include <iostream>
// template parameter pack needs to at the end
template < unsigned int i, char ... RHS >
struct t {
// can't copy-initialize an array from another array
constexpr static char const* s()
{ return t<i-1, ' ', char(i+'0'), RHS...>::s(); };
};
template <char ... RHS >
struct t<0, RHS...> {
// can't initialize a const array inside the class,
// need to use `constexpr`
constexpr static char arr[] = {'0', RHS..., '\0'};
constexpr static char const* s()
{ return arr; }
};
// need to define the array variable, it's ODR-used
template <char ... RHS >
constexpr char t<0, RHS...>::arr[];
int main() {
std::cout << t<5>::s(); // {'0',' ','1',' ','2',' ','3',' ','4',' ','5','\0'}
}
這是“更改最少”的版本:
#include <iostream>
#include <array>
template < unsigned int i, char ... RHS >
struct t {
constexpr static std::array<char, sizeof...(RHS)+2*i+2> s
= t<i-1, ' ', char(i+'0'), RHS...>::s;
};
template < unsigned int i, char ... RHS >
constexpr std::array<char, sizeof...(RHS)+2*i+2> t<i, RHS...>::s;
template <char ... RHS >
struct t<0, RHS...> {
constexpr static std::array<char, sizeof...(RHS)+2> s
= {{'0', RHS..., '\0'}};
};
template <char ... RHS >
constexpr std::array<char, sizeof...(RHS)+2>
t<0, RHS...>::s;
int main() {
std::cout << t<5>::s.data();
}
注意如何將數組復制到每個類中。 派生最多的(“頂級”)數組是通過.data()
,因此必須為主模板定義s
。 這里不需要為專業化定義s
。
除了使用靜態數據成員,您還可以在constexpr
函數內部構造數組:
constexpr static std::array<char, sizeof...(RHS)+2> arr()
{ return {{'0', RHS..., '\0'}}; }
缺點是此返回的數組具有自動生存期,因此您不能將其.data()
傳遞給基類。
這是將創建字符串的類似內容。 例如, Stringer<7>
將創建字符串"0 1 2 3 4 5 6 7"
。
template <uint32_t i>
struct Stringer
{
string str = Stringer<i - 1>().str + " " + to_string(i);
};
template <>
struct Stringer<0>
{
string str = "0";
};
int main(int argc, const char *argv[])
{
cout << Stringer<7>().str << endl;
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.