强制执行" noexcept"在std :: function上?

时间:2015-07-24 05:35:45

标签: c++ function noexcept

此代码编译并运行,抛出int

#include <functional>

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

void foo() { throw 1; }

int main()
{
    r(foo);
}

但是我希望编译器拒绝行r(foo);,因为r只应传递noexcept函数。 noexcept说明符似乎被忽略。有没有办法实现这个目标?

编辑:此问题与Is knowledge about noexcept-ness supposed to be forwarded when passing around a function pointer?不同,因为我要求补救措施,特别是在std::function的情况下。

1 个答案:

答案 0 :(得分: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");
      }
    }

    NoExceptDelegate(const NoExceptDelegate& other)
      : callback_(other.callback_)
    {
    }

    NoExceptDelegate& operator=(const NoExceptDelegate& other)
    {
      if (this != &other)
      {
        callback_ = other.callback_;
      }
      return *this;
    }

    NoExceptDelegate(NoExceptDelegate&& other)
      : callback_(move(other.callback_))
    {
    }

    NoExceptDelegate& operator=(NoExceptDelegate&& other)
    {
      callback_ = move(other.callback_);
      return *this;
    }

    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是可调用的。