Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从模板文件生成代码_C++_Templates_Boost - Fatal编程技术网

C++ 从模板文件生成代码

C++ 从模板文件生成代码,c++,templates,boost,C++,Templates,Boost,我写了一个模板文件,如下所示 Hello ${Name} I like ${food} 我想编写一个C++代码,它使用模板文件作为参考< /p>生成以下代码 Hello John I like Pasta I like Pasta I like Pasta 在C++中有没有办法做到这一点?我遇到了“ctemplate”,但我不相信。 我正在开发的应用程序是跨平台的。 (我想做一些类似于c#中的字符串模板的事情)标准库为日常正则表达式解析提供了极好的工具(这是您所需要的),请看这里 如果你从未

我写了一个模板文件,如下所示

Hello ${Name}
I like ${food}
<>我想编写一个C++代码,它使用模板文件作为参考< /p>生成以下代码
Hello John
I like Pasta
I like Pasta
I like Pasta
在C++中有没有办法做到这一点?我遇到了“ctemplate”,但我不相信。 我正在开发的应用程序是跨平台的。
(我想做一些类似于c#中的字符串模板的事情)

标准库为日常正则表达式解析提供了极好的工具(这是您所需要的),请看这里

如果你从未听说过regex,你需要了解它


或者,如果您关心性能,并且您的任务确实像您描述的那样简单,那么编写您自己的解析器应该非常直接,使用两个流并向前搜索${复制到输出流时转义序列,根据需要进行替换。

之前,我使用Boost Spirit编写了一个模板扩展“引擎”:

真是多才多艺

  • 支持嵌套扩展
  • 支持递归扩展
  • 支持动态扩展(例如,如果希望根据上下文使用不同的值扩展变量)
我刚刚根据您问题的宏语法对其进行了修改。请参见


更新 好的,因为性能似乎是主要目标,这里有一个高度优化的扩展引擎,在一个基准中:

#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();
}
#包括
#包括
#包括
#包括
模板
标准::字符串扩展(范围常量和键)
{
如果(键==“名称”)
返回“约翰”;
如果(键==“食品”)
返回“意大利面”;
返回“?”;
}
#包括
int main()
{
静态常量std::字符串消息\u模板=
“你好${Name}\n”
“我喜欢${food}\n”
;
标准::ostringstream builder;
builder.str().reserve(1024);//保留足够的空间,这并不重要,因为我们无论如何都会重用它

对于(size_t iterations=1ul),如果我理解得很好,您需要某种方法来解析
${xxxx}
。如果您的编译器支持C++11,请使用新的功能强大的正则表达式库。它几乎可以执行任何人需要的解析操作。我使用的是GNU-GCC编译器如果您的版本>4.6.1,您就可以了。我想用一种更干净的方法来实现这一点,就像在C中一样。我对C不太了解,但在C++11中,解析正则表达式是最干净的方法。这里有正则表达式的性能会有问题。假设我必须写一百万次“我喜欢意大利面”,这将是一个问题。@aditya我的解决方案完全在流模式下工作(除了宏本身的值,尽管也可以安排)在这里可以看到一个类似的任务,在没有Boost Spirit的情况下也解决了;添加了一个没有Boost的流媒体解决方案,速度非常快。