【问题标题】:Is there a way to return custom struct from a function in C++?有没有办法从 C++ 中的函数返回自定义结构?
【发布时间】:2021-10-19 04:46:57
【问题描述】:

我想知道是否有可能以某种方式从函数返回自定义结构。

实际用例:我有一个字符串形式的字典,由一些分隔符分隔。例如:FIX 消息:“8=FIX.4.4,8=MKT...”,在解析此消息时,我希望提取这些键值对,理想情况下以结构形式:{8:FIX. 4.4..},我可以为所有消息设置一个通用函数吗?什么数据结构可以是可能的返回类型?

用例似乎适合地图,但由于所有值的类型可能不同,我排除了它。我想获取它们各自类型的数据,即int为int,string为string,看到key我可以预先确定预期的类型,例如:34预期为整数,8预期为字符串等. 如果你们能分享你们的任何想法,那就太好了。

提前致谢!

【问题讨论】:

  • std::vector<:pair int>> fooFunction(std::pair input);
  • 不太清楚问题是什么或您要问什么。您想根据某些条件从同一个函数返回不同的类型吗?然后你需要某种类型的擦除,比如std::anystd::variant。但是,如果您解释您的用例,可能会有更好的选择。
  • 但由于所有值的类型可能不同请澄清。听起来它们至少可以表示为字符串。因此,如果您有其他想法,您应该解释它而不是让我们猜测。我猜你想要的不是std::map&lt;int, std::string&gt;
  • 我想获取它们各自类型的数据,即int as int,string as string,看到关键我可以预先确定预期的类型@ΦXocę웃Пepeúpaツ

标签: c++ function data-structures struct return-type


【解决方案1】:

正如评论中所说,您可以将数据存储在变体地图中:

#include <iostream>
#include <map>
#include <variant>
using std::cout, std::endl;

using var_t = std::variant<int, std::string, float, double>;

int main()
{
    std::map<int, var_t> myMap {
        { 10,  "hello world" },
        { 1,   5 },
        { 25,  1.0f },
        { 100, -8e20 },
    };

    // 1
    for (const auto& [key, value]: myMap) {
        cout << "[" << key << ": ";
        if (auto i_ptr = std::get_if<int>(&value)) {
            cout << *i_ptr;
        } else if (auto str_ptr = std::get_if<std::string>(&value)) {
            cout << *str_ptr;
        } else if (auto f_ptr = std::get_if<float>(&value)) {
            cout << *f_ptr;
        } else if (auto d_ptr = std::get_if<double>(&value)) {
            cout << *d_ptr;
        }
        cout << "]\n";
    }

    cout << endl << endl;

    // 2
    for (const auto& [key, value]: myMap) {
        std::visit([&key](auto& v) {
            cout << "[" << key << ": " << v << "]\n";
        }, value);
    }
    
    return 0;
}

https://godbolt.org/z/1PhYfq4hs

要在数据存储在变体中后访问您的数据,您可以

  1. 使用std::get_if 测试每种潜在类型。使用std::hold_alternative + std::get 也是一种选择。

  1. 创建一个访问者(lambda)并将其传递给您的变体std::visit

见:https://en.cppreference.com/w/cpp/utility/variant/

【讨论】:

    【解决方案2】:

    作为一种编译语言,您无法在运行时根据数据做出类型决策。因此,关键问题是您在编译代码时对类型的了解程度。

    • 如果您知道确切的类型,这只是一个模板函数
    • 如果您在编译时知道可能的类型列表,这是一个映射 问题
    • 如果这些类型可能由其他类型组成,那么您正在考虑使用库(如 JSON)

    因此,最通用的解决方案是返回 JSON document。只要你想要的数据可以表示为JSON。 Other libraries are also available

    一种更原生的方式是使用std::variant,它允许您说“这是可能类型的完整列表”(在编译时)。实际使用哪种类型可以在读取文件时决定。

    ---- 但是 ----

    请注意,计算的基本规律之一是,您的程序可以做的事情越多,它就越复杂。一个常见的经验法则是,您可以做到的最佳是将复杂性保持在特征数量的平方。所以 map, variant> 比 map 难写 4 倍。 添加 JSON 处理意味着您注入了无限数量的类型。这意味着您永远无法测试所有可能的类型。您的程序现在无法测试!实际上,当您处理 JSON 文档之类的事情时,您要做的第一件事就是拒绝不符合某些标准的文档,从而限制您必须处理的合法类型的数量,从而再次进行测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-07
      • 1970-01-01
      • 2010-09-30
      • 2021-11-09
      • 1970-01-01
      相关资源
      最近更新 更多