【发布时间】:2021-06-21 10:55:11
【问题描述】:
我正在实现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;
}
不幸的是,这两种方法都返回 false,我无法找到解决此问题的方法。
- 知道如何解决这个问题吗?
- 为什么标准库中没有检查函数是一元还是二元等的概念...
提前致谢。
编辑: 在编译了我收到的所有反馈之后(感谢大家)。这是原始实现的更好版本。
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;
}
【问题讨论】:
-
我不会为返回类型添加模板参数,而是将其设为
auto,因为它允许integer promotion。此外,您编写它的方式是在计算后执行static_cast。 -
顺便说一句,不确定您的参数“正确性”:
acc和a可能是R类型(这不是必需的std::integral) -
为什么要将自己编写的所有概念都放入
std命名空间?
标签: c++ templates c++20 c++-concepts