我有 C++ 代码,它包装任意 lambda 并返回 lambda 的结果。
template <typename F>
auto wrapAndRun(F fn) -> decltype(F()) {
// foo();
auto result = fn();
// bar();
return result;
}
这有效,除非F
回报void
(error: variable has incomplete type 'void'
)。我想用一个ScopeGuard
to run bar
,但我不想bar
运行如果fn
抛出。有任何想法吗?
附:后来我发现有解决这种不一致的提案 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0146r1.html.
您可以编写一个简单的包装类来处理这一部分:
template <class T>
struct CallAndStore {
template <class F>
CallAndStore(F f) : t(f()) {}
T t;
T get() { return std::forward<T>(t); }
};
并专攻:
template <>
struct CallAndStore<void> {
template <class F>
CallAndStore(F f) { f(); }
void get() {}
};
您可以通过小型工厂函数来提高可用性:
template <typename F>
auto makeCallAndStore(F&& f) -> CallAndStore<decltype(std::declval<F>()())> {
return {std::forward<F>(f)};
}
然后使用它。
template <typename F>
auto wrapAndRun(F fn) {
// foo();
auto&& result = makeCallAndStore(std::move(fn));
// bar();
return result.get();
}
编辑:与std::forward
铸入内部get
,这似乎也可以正确处理从函数返回的引用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)