如何正确声明二元运算的概念

How to declare a concept for binary operations properly

我正在实施 elements of programming 书中的通用快速功率算法。

这是一个非常幼稚的版本

template <typename R, typename I, typename Op>
requires std::integral<R> && std::integral<I> && std::is_binary_op<Op, R, I, I>
R power(I acc, I a, I n, Op op) {
  while (n-- != I{0}) {
    acc = op(acc, a);
  }
  return acc;
}

我也在尝试对传递给函数的类型强制执行要求。但是当我试图声明一个关于二进制操作的概念时,我被卡住了。这是我想出的两种方法。

// first approach
namespace std {
template <typename Op, typename Ret, typename Arg1, typename Arg2>
concept is_binary_op = std::is_same<Op, Ret(Arg1, Arg2)>::value;
}

// second approach
namespace std {
template <typename Op, typename Ret, typename Arg1, typename Arg2>
concept is_binary_op = std::is_same < typename std::function<Op>,
typename std::function<Ret(Arg1, Arg2)> >::value;
}  

不幸的是,这两种方法 return 都是错误的,我找不到解决这个问题的方法。

  1. 知道如何解决这个问题吗?
  2. 为什么标准库中没有检查函数是一元函数还是二元函数等的概念...

提前致谢。

编辑: 在整理了我收到的所有反馈后(感谢大家)。这是原始实现的更好版本。

namespace std {
template <typename Op, typename Arg1, typename Arg2>
concept binary_op = std::is_invocable<Op, Arg1, Arg2>::value;
}  // namespace std

template <std::integral I, std::binary_op<I, I> Op>
auto power(I acc, I a, I n, Op op) {
  while (n-- != I{0}) {
    acc = op(acc, a);
  }
  return acc;
}

Any idea how to fix this ? Why there are no concepts in the standard library checking if a function is unary or binary, etc...

There is a trait,用于特定参数类型。您不应该向 namespace std.

添加概念
template <typename Op, typename Arg1, typename Arg2>
concept binary_op = std::is_invocable_v<Op, Arg1, Arg2>;

template <typename Op, typename Ret, typename Arg1, typename Arg2>
concept binary_op_r = std::is_invocable_r_v<Ret, Op, Arg1, Arg2>;

N.b。你可以更简洁地表达power

template <std::integral R, std::integral I, binary_op_r<R, I, I> Op>
requires std::is_assignable_v<I, R>
R power(I acc, I a, I n, Op op) {
  while (n-- != I{0}) {
    acc = op(acc, a);
  }
  return acc;
}