26

基本的に、私が達成したいのは、登録された callable (関数、ラムダ、call 演算子を含む構造体) が正しい署名を持っていることをコンパイル時に検証することです (エラー メッセージが表示される可能性があります)。記入例(static_assert記入欄の内容):

struct A {
  using Signature = void(int, double);

  template <typename Callable>
  void Register(Callable &&callable) {
    static_assert(/* ... */);
    callback = callable;
  }

  std::function<Signature> callback;
};
4

6 に答える 6

2

これは、C ++ 17を使用できる場合の@ R2RTの回答の別のバージョンです。トレイトis_invocable_rを使用して仕事をすることができます:

struct Registry {
  std::function<void(int, double)> callback;

  template <typename Callable, 
      std::enable_if_t<
          std::is_invocable_r_v<void, Callable, int, double>>* = nullptr>
  void Register(Callable callable) {
    callback = callable;
  }
};

int main() {
  Registry r;
  r.Register([](int a, double b) { std::cout << a + b << std::endl; });
  r.callback(35, 3.5);
}

印刷する 38.5

の良いところは、呼び出し可能な引数の型だけでstd::is_invocable_r、戻り値の型と引数の型を制御できることです。std::is_invocable

于 2021-03-12T18:58:25.353 に答える