私もこの問題に遭遇しました。私の解決策は、委譲オブジェクトを使用することでした(への委譲std::function
)。デリゲートには no-except 仕様があります。まだ改善される可能性があります(移動の追加など)。
ここに行きます:
#include <functional>
template <class FuncT>
struct NoExceptDelegate;
template <class R, class ... Args >
struct NoExceptDelegate<R(Args...)>
{
NoExceptDelegate(std::function<R(Args...)>&& callback)
: callback_(move(callback))
{
if (!callback_)
{
throw std::invalid_argument( "NoExceptDelegate requires a valid callback");
}
}
template <class...ArgsU>
R operator()(ArgsU&&... args) noexcept
{
return callback_(std::forward<ArgsU>(args)...);
}
private:
std::function<R(Args...)> callback_;
};
これは通常、提供されたハンドラーがスローしないことを示すために、非同期インターフェイスのコントラクトとして使用されます。
struct Interface
{
virtual void doSomethingAsynchronous(
NoExceptDelegate<void(int)> onCompletionResult) = 0;
//...etc
};
クライアントはコールバック プロバイダーでNoExceptDelegate
あるため、提供するプロバイダーからの約束は失敗しません。プロバイダーは、少なくともstd::function
provided が呼び出し可能であることを確認する必要があります。