C++14+Boost:基于DSL格式化已知类型参数列表的实现问询
我现在有点摸不着头绪该从哪里入手实现这个功能,要是表述有疏漏还请多多包涵。
我的开发环境是C++14结合Boost,目前已经定义了这些结构体:
struct Character { std::string name; }; struct Item { std::string name; }; struct Map { std::string name; };
同时还有一系列接收这些结构体作为参数、返回std::string的函数:
std::string name(const Character& character) { return character.name; } std::string itemName(const Item& item) { return item.name; } std::string mapName(const Map& map) { return map.name; }
期望实现的核心功能
我希望能写出这样的代码:
Character character = {}; Map map = {}; character.name = "David"s; map.name = "Town"s; std::string formatted = i18n::localize("Hello, { name($1) }! You are in { mapName($2) }.", character, map); assert(formatted.compare("Hello, David! You are in Town.") == 0);
简单来说,localize函数要能接收可变数量的结构体参数,按照传入的DSL字符串完成格式化。
扩展需求与遇到的痛点
- 要支持类似
possessive($1)这类函数,比如获取角色的所有格短语——这个短语会根据角色是否为当前玩家而变化 - 同一DSL要能适配多语言,同时保持参数数量一致;不同语言的DSL字符串要能调用对应语言的专属函数
- 我遇到的核心痛点:如果不写大量条件分支,仅传入待格式化对象给
localize时,没办法预先知道该调用哪个函数 - 另外,DSL语法错误、或者DSL里的函数无法适配指定类型时,属于用户错误,
localize可以直接抛出异常 - 我考虑过两种函数注册的方式,不确定是否可行:
第一种是通用注册:
第二种是按类型区分的注册:i18n::register_formatter( name ); i18n::register_formatter( itemName );i18n::register_character_formatter( name ); i18n::register_item_formatter( itemName );
参考思路(Rust中的实现)
我知道在Rust里可以通过枚举来处理这类分发:
return match value { Value::Character(ref chara) => dispatch_chara(chara), Value::Item(ref item) => dispatch_item(item), Value::Map(ref map) => dispatch_map(map), }
我的问题
请问在C14中实现这类功能需要用到哪些模板技术?这个需求在C14里是否可行?
内容的提问来源于stack exchange,提问作者Sinuous514
相关产品推荐
相关产品推荐

