【问题标题】:how to return an unknown value in c++如何在C++中返回一个未知值
【发布时间】:2022-01-23 10:53:49
【问题描述】:
auto list::at(int index)
{
    for (auto node : VECTOR_OF_INT)
        if (node.getIndex() == index)
            return node.getValue();

    for (auto node : VECTOR_OF_DOUBLE)
        if (node.getIndex() == index)
            return node.getValue();

    for (auto node : VECTOR_OF_STRING)
        if (node.getIndex() == index)
            return node.getValue();
}

这是为了让我的列表类找到索引,我想返回一个 int、double 或 string,但我不知道如何帮助。

【问题讨论】:

  • 您可能正在寻找std::any。
  • 首先,函数并非在所有情况下都返回值。希望您会看到并解决编译警告,否则它是未定义的行为。您可以使用std::any 或std::variant。
  • @zdf std::any 非常重。我会用一个全面的 std::variant 代替它,这很便宜。
  • 我没有太多信息,但我猜这是一个设计问题。这里唯一有意义的方法是使用模板。函数的返回类型是固定的。 auto 在这里无济于事,除非你真的使用模板。
  • 我怀疑我们正在查看meta.stackexchange.com/questions/66377/what-is-the-xy-problem,所以请退后一步,用您所询问的步骤解释您想要解决的问题。

标签: c++


【解决方案1】:

对于缺乏细节的问题,很难给出可靠的答案。但我仍然想提出一个潜在的解决方案。请记住,这只是一个建议。

您可能会返回一个包含 3 个 std::optional 值的 std::tuple:

auto list::at(const int index)
{
    std::tuple< std::optional<int>, std::optional<double>,
                std::optional<std::string> > returnValue;

    for (auto node : VECTOR_OF_INT)
    {
        if (node.getIndex() == index)
        {
            std::get<0>(returnValue) = node.getValue();
            std::get<1>(returnValue) = { };
            std::get<2>(returnValue) = { };
            return returnValue;
        }
    }

    if ( !std::get<0>(returnValue).has_value( ) )
    {
        std::get<0>(returnValue) = { };
    }

    for (auto node : VECTOR_OF_DOUBLE)
    {
        if (node.getIndex() == index)
        {
            std::get<1>(returnValue) = node.getValue();
            std::get<2>(returnValue) = { };
            return returnValue;
        }
    }

    if ( !std::get<1>(returnValue).has_value( ) )
    {
        std::get<1>(returnValue) = { };
    }

    for (auto node : VECTOR_OF_STRING)
    {
        if (node.getIndex() == index)
        {
            std::get<2>(returnValue) = node.getValue();
            return returnValue;
        }
    }

    if ( !std::get<2>(returnValue).has_value( ) )
    {
        std::get<2>(returnValue) = { };
    }

    return returnValue;
}

但在不了解您的情况的情况下,我不能说这是否是一种好方法。

【讨论】:

  • 您确实建议了一个次优的解决方案:调用者最多需要对 std::optional::has_value() 进行 2 次查询才能确定返回的类型。此外,所需空间的下限是类型大小的总和,而不是类型大小的最大值 + 变体/联合的类型信息 + 类型信息的最大值。我投反对票的原因是您的代码根本不正确:您总是覆盖最后一次迭代中的值,而不是返回第一个匹配项,即使找到匹配项,除了继续搜索其他类型,即使已找到所需信息。
  • @fabian 感谢您提到这一点。我修好了它。请看一下。
【解决方案2】:

看到你的问题不清楚,但假设你有三个不同类型的节点向量(int、float、std::string),并且你想根据索引返回一个值。在这种情况下,如果您使用的是 C++17 或更高版本,则可以使用 std::variant。

using MyVariant = std::variant<int,double,std::string>;
MyVariant list::at(int index)
{
    ...
}

对于 C++14 或更低版本,您可以查找union(最好将其包装在一个类中)或使用void*(不推荐)。或者对 C++11 和 C++14 使用 boost::variant。

【讨论】:

  • 是的,我确实有节点的 int、string 等向量
  • 也许我们可以做一个 colab
  • 你到底想创造什么?您可以查看我的项目,它会创建表格,其中每列可以有不同的类型。它可以以电子表格函数样式操作表格数据。 github.com/KSCreator/KMTable
  • 我不能使用 boost 导致 VS Code 并且编译器告诉 boost in not defined
  • 您需要安装 boost 库,然后您需要使用 -I\path\to\boost\headers 告诉编译器您的库存在于何处。它有很多只有头文件的库,所以你不需要链接它。
猜你喜欢
  • 1970-01-01
  • 2018-08-09
  • 1970-01-01
  • 1970-01-01
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
  • 2021-09-02
相关资源
最近更新 更多