将函数的返回值存储在元组中 [英] Storing return values of functions in a tuple
问题描述
考虑
#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);
}
这有点重复,但它可以为任何类型的函子完成工作,任何参数列表和任何返回类型。
值得注意的是,有一个提案让
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);
}
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屋!