11

このコードはコンパイルおよび実行され、以下をスローしintます。

#include <functional>

void r( std::function<void() noexcept> f ) { f(); }

void foo() { throw 1; }

int main()
{
    r(foo);
}

ただし、関数のみを渡す必要があるr(foo);ため、コンパイラーに行を拒否してもらいたいと思います。指定子は無視されているようです。それを達成する方法はありますか?rnoexceptnoexcept

編集:この質問は、関数ポインターを渡すときに noexcept-ness に関する知識が転送されることになっていますか? とは異なります。特に の場合、私は救済を求めているからですstd::function

4

1 に答える 1

1

私もこの問題に遭遇しました。私の解決策は、委譲オブジェクトを使用することでした(への委譲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::functionprovided が呼び出し可能であることを確認する必要があります。

于 2015-07-28T11:29:27.503 に答える