在C++中,我想创建一个定义数据管道的函数对列表。例如,给定如下内容:
FieldName: "F1"
ParserFunction: X ParseX(string s)
DestinationFn: void Consume(X& f1)
FieldName: "F2"
ParserFunction: Y ParseY(string s)
DestinationFn: void Consume(Y& f2)
字符串
我希望能够将此列表存储在一个数据结构中,例如Map,其中给定FieldName和Data的字符串,调用正确的解析器和消费者。
到目前为止,我想到的最好的方法是这样的:
using ParseResult = std::variant< X, Y >;
map< string, pair< std::function<ParseResult(string)>, std::function<void(ParseResult)>>
型
这使得解析器可以自然地编写(并且可以重用现有的解析器):
int StringToInt(const string& s) { return 42; }
型
但消费者必须使用变体:
void ConsumeInt(ParseResult i) { foo = std::get<int>(i); }
型
这是可行的,但如果参数实际上不携带整数,则会产生运行时错误。这也意味着对于任何给定的应用程序,变量类型必须声明所有可能的类型。对于一个很长的转换器列表,可能有大量的类型。
有没有一种方法可以声明Map的内容,使每行在构造时都是完全类型安全的,但行是类型可变的(或类型擦除的)?
换句话说,我想要:
void TypesafeIntegerSink(int i) { ... }
型
和我的map初始化器如下所示:
mymap = {
{ "F1", { StringToInt, TypesafeIntegerSink } },
{ "F2", { StringToX, TypesafeXSink } },
....
}
型
我想知道是否有一种聪明的方法来构造它,这样如果F1解析器没有返回一个int,或者如果F1接收器没有接受一个int,它就无法编译。
1条答案
按热度按时间wwtsj6pe1#
显而易见的解决方案是使用一个函数来解析和消费字符串,并直接使用一个小lambda来构建它:
字符串