C++ 可组合的一元lambda/std::函数,带std::可选
我正在尝试构建一个C++ 可组合的一元lambda/std::函数,带std::可选,c++,templates,c++17,C++,Templates,C++17,我正在尝试构建一个过滤器类型,它可以作为一个可组合的错误处理可调用(即,一个可能带有>=)的monad,在C++17中(理想情况下)与lambda和std::function(不需要与旧标准兼容)。理想情况下,工作原理如下: // two example Filter's instantiated from lambda's Filter g = [](const int a, const int b) -> float { return a + b;
过滤器
类型,它可以作为一个可组合的错误处理可调用(即,一个可能带有>=)的monad,在C++17中(理想情况下)与lambda和std::function
(不需要与旧标准兼容)。理想情况下,工作原理如下:
// two example Filter's instantiated from lambda's
Filter g = [](const int a, const int b) -> float {
return a + b;
};
Filter f = [](const float c) -> std::optional<int> {
if c < 0 return std::nullopt;
else return c + 1;
};
// compose them - only two right now for brevity
auto h = f << g; // so that this implements f(g(...))
// and then later call them with some arguments
h(1.0, 2.0);
由两个简单函数组成,
f不确定是否理解您的代码,但。。。在我看来,问题出在这一部分(删除了注释并简化了一点)
什么类型是gresult
我假设您希望它是某种类型的std::optional
,因此您测试它是否有效(if(gresult)
),并将其传递给下面的eval()
但是将g()
和h()
结合起来会发生什么呢?并结合f()
如果我理解正确,h()
在前面执行,并返回一个int
;因此,gresult
是一个int
当你检查的时候
if (gresult)
您不检查gresult
是否有效,但检查gresult
是否为零
但这是可行的(我的意思是…编译),整数值用于调用等待int常量的g()
但是当g()的结果
(这是一个std::optional
)用于调用f()
(它等待int
),您可以
if (gresult)
正确检查gresult
是否有效,但在调用f()
传递给f()
astd::optional()
,而不是int
不确定解决方案(不确定您到底想要什么以及std::option
扣减指南),但在我看来,您应该强制执行gresult
是某种类型的std::option
std::option gresult{ other( args.value()... ) };
所以下面的检查
if ( gresult )
关于gresult
的有效性,接下来必须将gresult
的值传递给以下函数
return this->eval_( gresult.value() );
请注意,在以下代码中
int a;
std::optional b{a};
std::optional c{b};
static_assert( std::is_same_v<decltype(b), std::optional<int>> );
static_assert( std::is_same_v<decltype(c), std::optional<int>> );
inta;
std::可选的b{a};
std::可选的c{b};
静态断言(std::is_same_v);
静态断言(std::is_same_v);
b
和c
都是std::可选的
我是说。。。使用std::optional
的演绎指南,如果参数是std::optional
,则结果类型相同
我想这应该对你有用,但我不确定你到底想要什么。自动操作符是TReturn是一个打字错误吗?@KorelK No-返回类型是f(g(…)
是f
的返回类型,它是TReturn
。所以,f(g(…)
是来自TOArgs->TReturn的函数
哦,对不起,错过了类上面的类型。您想要什么h(1.0,2.0)
甚至意味着?g
是一元的,但你要给它传递两个参数……然后f
是二进制的,你要给它传递一个参数。这是不是正好相反?@Barry.demonics-我在提供示例时得到了f的顺序,但不正确(注意:在提供的示例代码中它是正确的).我已经更新了问题,很抱歉造成混淆!
return this->eval_(gresult);
std::option gresult{ other( args.value()... ) };
if ( gresult )
return this->eval_( gresult.value() );
int a;
std::optional b{a};
std::optional c{b};
static_assert( std::is_same_v<decltype(b), std::optional<int>> );
static_assert( std::is_same_v<decltype(c), std::optional<int>> );