[英]c++ numerical parser using template metaprogramming
i have been working for around 4 hours tryng to find a way that this code compile: 我已经尝试了大约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'}
}
i from another post, that i dont have the link, but this code is tryng to parser a number to char at compile time. 我从另一篇文章中得知,我没有链接,但是这段代码试图在编译时将一个数字解析为char。 any help why this code is not compiling?
任何帮助为什么此代码无法编译? thx in advance!
提前谢谢!
#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'}
}
And here's a version with "minimal changes": 这是“更改最少”的版本:
#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();
}
Note how the array is copied into each class. 注意如何将数组复制到每个类中。 The most-derived ("top-level") array is odr-used via
.data()
, so definition of s
for the primary template is necessary. 派生最多的(“顶级”)数组是通过
.data()
,因此必须为主模板定义s
。 The definition of s
for the specialization isn't required here. 这里不需要为专业化定义
s
。
Instead of using a static data member, you could also construct the array inside a constexpr
function: 除了使用静态数据成员,您还可以在
constexpr
函数内部构造数组:
constexpr static std::array<char, sizeof...(RHS)+2> arr()
{ return {{'0', RHS..., '\0'}}; }
The drawback is that this returned array has automatic lifetime, so you can't pass its .data()
to the base classes. 缺点是此返回的数组具有自动生存期,因此您不能将其
.data()
传递给基类。
Here is something similar that will create a string. 这是将创建字符串的类似内容。 For example,
Stringer<7>
will create the string "0 1 2 3 4 5 6 7"
. 例如,
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.