将函数的返回值存储在元组中 [英] Storing return values of functions in a tuple

查看:111
本文介绍了将函数的返回值存储在元组中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑

  #include< tuple> 

模板< typename ... F>
自动执行(F ... f){
return std :: make_tuple(f(0)...);
}

int foo(int){return 5; }
int bar(int){return 3; }

int main(){
auto tuple = execute(foo,bar);
}

什么是好的解决方法,以便bar可以返回void?



我试过这个,但它不会编译:

  #include<元组GT; 

struct Void {};

模板< typename T>
T check(T n){return n; }

无效检查(void){return Void {}; }

模板< typename ... F>
自动执行(F ... f){
return std :: make_tuple(check(f(0))...);
}

int foo(int){return 5; }
void bar(int){}

int main(){
auto tuple = execute(foo,bar);

更新:我有一个试验性的解决方案,但只有当我们知道传递的参数始终为int 0。我将尝试使其在任何常规设置中都能工作。或者使用std ::可选,就像史蒂夫建议的那样。

  #include< tuple> 
#include< type_traits>

struct Void {};

模板< typename F>
auto_unit_h(F f,std :: enable_if_t<!std :: is_void_v< std :: result_of_t< F(int)>>> * = nullptr){
const auto result = f (0);
返回结果;
}

模板< typename F>
auto_unit_h(F f,std :: enable_if_t< std :: is_void_v< std :: result_of_t< F(int)>>> * = nullptr){
f(0);
return Void {};
}

模板< typename ... F>
自动执行(F ... f){
return std :: make_tuple(execute_h(f)...);
}

int foo(int){return 5; }
void bar(int){}

int main(){
auto tuple = execute(foo,bar);


解决方案

您可以使用 std :: enable_if 以及一个封装函数来返回函数返回一个 Void 对象,该函数返回 void

  #include< tuple> 
#include< type_traits>

struct Void {};

模板< typename Func,typename ... Args>
自动检查(Func func,Args&& ... args)
- > std :: enable_if_t<!std :: is_void< decltype(func(std :: forward< args>(args)...))> :: value,decltype(func(std :: forward< Args> ...))>
{
return func(std :: forward< Args>(args)...);
}

模板< typename Func,typename ... Args>
自动检查(Func func,Args&& ... args)
- > std :: enable_if_t< std :: is_void< decltype(func(std :: forward< Args>(args)...))> :: value,Void>
{
func(std :: forward< Args>(args)...); return Void {};
}

模板< typename ... F>
自动执行(F ... f){
return std :: make_tuple(check(f,0)...);
}

int foo(int){return 5; }
void bar(int){}

int main(){
auto tuple = execute(foo,bar);
}

现场演示

这有点重复,但它可以为任何类型的函子完成工作,任何参数列表和任何返回类型。



值得注意的是,有一个提案> void 一个常规类型,它可以让你避免所有这些麻烦,但我不确定那是什么状态或是否会被接受。


Consider

#include <tuple>

template <typename... F>
auto execute (F... f) {
    return std::make_tuple(f(0)...);
}

int foo(int) { return 5; }
int bar(int) { return 3; }

int main() {
    auto tuple = execute(foo, bar);
}

What is a good workaround so that bar can return void?

I tried this, but it won't compile:

#include <tuple>

struct Void { };

template <typename T>
T check(T n) { return n; }

Void check(void) { return Void{}; }

template <typename... F>
auto execute (F... f) {
    return std::make_tuple(check(f(0))...);
}

int foo(int) { return 5; }
void bar(int) { }

int main() {
    auto tuple = execute(foo, bar);
}

Update: I have a tentative solution, but it only works if we know that the arguments passed is always int 0. I'll try to make it work in any general setting. Or perhaps use std::optional like Steve suggested.

#include <tuple>
#include <type_traits>

struct Void { };

template <typename F>
auto execute_h (F f, std::enable_if_t<!std::is_void_v<std::result_of_t<F(int)>>>* = nullptr) {
    const auto result = f(0);
    return result;  
}

template <typename F>
auto execute_h (F f, std::enable_if_t<std::is_void_v<std::result_of_t<F(int)>>>* = nullptr) {
    f(0);
    return Void{};  
}

template <typename... F>
auto execute (F... f) {
    return std::make_tuple(execute_h(f)...);
}

int foo(int) { return 5; }
void bar(int) { }

int main() {
    auto tuple = execute(foo, bar);
}

解决方案

You can use std::enable_if and a wrapper function to return a Void object for functors that return void:

#include <tuple>
#include <type_traits>

struct Void { };

template <typename Func, typename... Args>
auto check(Func func, Args&&... args)
    -> std::enable_if_t<!std::is_void<decltype(func(std::forward<Args>(args)...))>::value, decltype(func(std::forward<Args>(args)...))>
{
    return func(std::forward<Args>(args)...);
}

template <typename Func, typename... Args>
auto check(Func func, Args&&... args)
    -> std::enable_if_t<std::is_void<decltype(func(std::forward<Args>(args)...))>::value, Void>
{
    func(std::forward<Args>(args)...); return Void{};
}

template <typename... F>
auto execute (F... f) {
    return std::make_tuple(check(f, 0)...);
}

int foo(int) { return 5; }
void bar(int) { }

int main() {
    auto tuple = execute(foo, bar);
}

Live demo

It's a bit repetitive, but it gets the job done for any type of functor, any argument list, and any return type.

It's worth noting that there's a proposal floating around to make void a regular type that would let you avoid all of these hassles, but I'm not sure what the status of that is or if it will ever be accepted.

这篇关于将函数的返回值存储在元组中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆