从 std::apply 中的折叠表达式捕获返回值

问题描述 投票:0回答:1

我有一个简单的片段,试图说明我正在尝试做什么。 我将几个类实例打包在一个元组中,并使用 std::apply 迭代它们。 我想捕捉两个值:

  1. 如果找到匹配的密钥
  2. 如果找到一个键,返回
    do_test
    调用的结果

我在变量

fn_ret
中捕获 (2),但是对于 (1),我无法判断在遍历元组时是否找到了键。我想我可能需要先以某种方式存储/获取
search_tuple(args)
的结果,然后再将其传递给折叠表达式。我该怎么做?

#include <iostream>
#include <tuple>

using namespace std;

class foo
{
    public:
    foo(int i) : key_(i){}
    
    int get_key()
    {
        return key_;
    }

    int do_test()
    {
        std::cout << "ran test for key=" << key_ << "\n";
        return -1;
    }
    private:
    int key_;
};

int main()
{
    std::tuple tup { foo{1}, foo{2}, foo{3}, foo{4}, foo{5}, foo{6}, foo{7}, foo{8} };
    int key = 4;
    int fn_ret = 0;
    std::apply
        (
            [key, &fn_ret](auto&... args)
            {
                auto search_tuple = [key, &fn_ret](auto& x) {
                    int foo_key = x.get_key();
                    cout << "current key=" << foo_key << "\n";
                    if (foo_key == key)
                    {
                        std::cout << "found matching key, running test!\n";
                        fn_ret = x.do_test();
                        return 0;
                    }
                    return -1;
                };
                (search_tuple(args) && ...);
            }, tup
        );
    return 0;
}
c++ templates c++17 variadic-templates
1个回答
1
投票

以下代码在合理范围内有效。它在

fn_ret
中存储了一个特殊的初始值,用于检查是否找到了密钥。相反,可以通过引用从 main 传递一个额外的布尔变量以及
key
fn_ret
.

#include <iostream>
#include <tuple>

using namespace std;

class foo
{
    public:
    foo(int i) : key_(i){}
    
    int get_key()
    {
        return key_;
    }

    int do_test()
    {
        std::cout << "ran test for key=" << key_ << "\n";
        return key_*key_; // Some operation on the key
    }
    private:
    int key_;
};

int main()
{
    std::tuple tup { foo{1}, foo{2}, foo{3}, foo{4}, foo{5}, foo{6}, foo{7}, foo{8} };
    int key = 10;
    int fn_ret = -1;
    bool key_fnd = false;
    std::apply
        (
            [key, &fn_ret, &key_fnd](auto&... args)
            {
                auto search_tuple = [key, &fn_ret, &key_fnd](auto& x) {
                    int foo_key = x.get_key();
                    cout << "current key=" << foo_key << "\n";
                    if (foo_key == key)
                    {
                        std::cout << "found matching key, running test!\n";
                        key_fnd = true;
                        fn_ret = x.do_test();
                        return 0;
                    }
                    return -1;
                };
                (search_tuple(args) && ...);
            }, tup
        );
    if (!key_fnd) {
      std::cout<<"The key was not found"<<std::endl;
    }
    else {
      std::cout<<"The result of running the test on key "<<key;
      std::cout<<" is "<<fn_ret<<std::endl;
    }

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.