从模板文件生成代码
Code generation from template file
我编写了一个模板文件,如下所示
Hello ${Name}
I like ${food}
我想写一个c++代码,它使用模板文件作为参考生成以下代码
Hello John
I like Pasta
I like Pasta
I like Pasta
在c++中有办法做到这一点吗?我遇到了"模板",但我不相信。我正在开发的应用程序是跨平台的。(我想在c#中做一些类似字符串模板的东西)
我以前用Boost Spirit写过一个模板扩展'引擎':
- 用Boost编译一个简单的解析器。
它真的很通用
- 支持嵌套扩展
- 支持递归展开
- 支持动态扩展(例如,如果您希望根据上下文使用不同的值展开变量)
我刚刚把它适应了你的问题的宏语法。查看Live On Coliru
好的,因为性能似乎是主要目标,下面是一个高度优化的扩展引擎,在基准测试中:
#include <string>
#include <sstream>
#include <map>
#include <boost/utility/string_ref.hpp>
template <typename Range>
std::string expand(Range const& key)
{
if (key == "Name")
return "John";
if (key == "food")
return "Pasta";
return "??";
}
#include <iostream>
int main()
{
static const std::string msg_template =
"Hello ${Name}n"
"I like ${food}n"
;
std::ostringstream builder;
builder.str().reserve(1024); // reserve ample room, not crucial since we reuse it anyways
for (size_t iterations = 1ul << 22; iterations; --iterations)
{
builder.str("");
std::ostreambuf_iterator<char> out(builder);
for(auto f(msg_template.begin()), l(msg_template.end()); f != l;)
{
switch(*f)
{
case '$' :
{
if (++f==l || *f!='{')
{
*out++ = '$';
break;
}
else
{
auto s = ++f;
size_t n = 0;
while (f!=l && *f != '}')
++f, ++n;
// key is [s,f] now
builder << expand(boost::string_ref(&*s, n));
if (f!=l)
++f; // skip '}'
}
}
default:
*out++ = *f++;
}
}
// to make it slow, uncomment:
// std::cout << builder.str();
}
std::cout << builder.str();
}
它在~0.775秒内运行2^22(4,194,304)次迭代
请参阅Live On Coliru(其中运行时间约为1.8秒)
标准库具有出色的日常正则表达式解析功能(这正是您所需要的),请查看此处的文档。
如果你从未听说过regex,你需要了解它——这至少是一个概述细节的地方。
或者,如果你关心性能,你的任务就像你描述的那样简单,那么编写你自己的解析器应该非常直接,使用两个流,并在复制到输出流时寻找${转义序列,同时根据需要替换。
相关文章:
- 在C++代码中包含opencv时,使用ctypes创建.so文件
- 此代码编译良好,但文件未创建?请指出错误
- 找不到Linux Visual Studio代码C++文件
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- Visual Studio代码文件未输出
- 是否可以使用 GCC 编译具有特定编译器标志的代码文件的一部分?
- 如何从ifstream加载LLVM比特代码文件
- 在同一代码文件中包括 Directx 9 和 10
- 如果我只想要架构良好的工作区,但不一定是分开的编译,如何在C++中组织头/代码文件
- 使用 Eclipse 运行.exe C 代码文件
- 是否可以稍后在代码(C++ I/O 文件)中使用输出文件作为输入文件
- 匿名命名空间-在头文件和代码文件中都有意义
- 代码文件外的代码文档
- 在静态库中硬编码的代码文件和头路径
- 更快地解析代码文件
- 为什么有些代码文件使用 close() 而不包含 unistd.h
- 在代码(.c文件)我如何找到linux发行版名称版本
- 在一个代码文件中使用头文件,反之亦然
- SonarQube未分析带有警告的C++代码文件不在项目目录下
- Qt 创建器代码文件重构