C++在map中存储变量类型

5ktev3wc  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(123)

在C++中,我想创建一个定义数据管道的函数对列表。例如,给定如下内容:

  1. FieldName: "F1"
  2. ParserFunction: X ParseX(string s)
  3. DestinationFn: void Consume(X& f1)
  4. FieldName: "F2"
  5. ParserFunction: Y ParseY(string s)
  6. DestinationFn: void Consume(Y& f2)

字符串
我希望能够将此列表存储在一个数据结构中,例如Map,其中给定FieldName和Data的字符串,调用正确的解析器和消费者。
到目前为止,我想到的最好的方法是这样的:

  1. using ParseResult = std::variant< X, Y >;
  2. map< string, pair< std::function<ParseResult(string)>, std::function<void(ParseResult)>>


这使得解析器可以自然地编写(并且可以重用现有的解析器):

  1. int StringToInt(const string& s) { return 42; }


但消费者必须使用变体:

  1. void ConsumeInt(ParseResult i) { foo = std::get<int>(i); }


这是可行的,但如果参数实际上不携带整数,则会产生运行时错误。这也意味着对于任何给定的应用程序,变量类型必须声明所有可能的类型。对于一个很长的转换器列表,可能有大量的类型。
有没有一种方法可以声明Map的内容,使每行在构造时都是完全类型安全的,但行是类型可变的(或类型擦除的)?
换句话说,我想要:

  1. void TypesafeIntegerSink(int i) { ... }


和我的map初始化器如下所示:

  1. mymap = {
  2. { "F1", { StringToInt, TypesafeIntegerSink } },
  3. { "F2", { StringToX, TypesafeXSink } },
  4. ....
  5. }


我想知道是否有一种聪明的方法来构造它,这样如果F1解析器没有返回一个int,或者如果F1接收器没有接受一个int,它就无法编译。

wwtsj6pe

wwtsj6pe1#

显而易见的解决方案是使用一个函数来解析和消费字符串,并直接使用一个小lambda来构建它:

  1. std::map<std::string, std::function<void(std::string)>> mymap = {
  2. { "F1", [](std::string in) { TypesafeIntegerSink(StringToInt(in)); } },
  3. { "F2", [](std::string in) { TypesafeXSink(StringToX(in)); } },
  4. /* ... */
  5. };

字符串

相关问题