我有一个 step(f)
函数:
在调用
f
之前执行一些代码。调用
f()
。调用
f
后执行一些代码。返回
f
的结果值如果f
不返回void
。
由于上述第四点,实现 step
的一小段代码让我更加困扰:
template <typename TF>
auto step(TF&& f)
{
// Execute some actions before `f`.
do_something();
using f_return_type = decltype(f());
return static_if(std::is_same<f_return_type, void>{})
.then([](auto&& xf) mutable
{
// Do not return anything if `xf` returns void.
xf();
// Execute some actions after `f`.
do_something_after_f();
})
.else_([](auto&& xf) mutable
{
auto result = xf();
// Execute some actions after `f`.
do_something_after_f();
return result;
})(std::forward<TF>(f));
}
(注意重复调用 f
和 do_something_after_f
。)
我必须使用某种条件编译时(模板特化或static_if
,如示例所示)根据f<进行分支
的返回类型。
理想情况下,我希望这样可以编译:
template <typename TF>
auto step(TF&& f)
{
// Execute some actions before `f`.
do_something();
decltype(auto) eventual_result = f();
// Execute some actions after `f`.
do_something_after_f();
return result;
}
但不是,因为eventual_result
可以是void
,这是一个不完整的类型。
是否有任何方法可以重构此代码以避免重复调用 f()
和 do_something_after_f()
?
最佳答案
您可以通过将返回语句放入局部变量的析构函数中,让 do_something_after_f()
在返回语句之后运行。
struct Cleanup {
~Cleanup() { do_something_after_f(); }
} cleanup;
return f(); // it's legal to return a void expression in C++
关于c++ - 如果 `f` 具有非空返回类型,则返回 `f` 的结果——如何重构此模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37489952/