我正在使用一个API,该API接受带有单个参数的函数作为回调。回调函数接受一个特定类型的参数,为简单起见,我将说它返回一个bool
。我试图整合的主要内容是范围检查功能。我的直觉是写这样的东西:
template<class T, T min, T max>
constexpr bool in_range(T val) {
return (val >= min && val <= max);
}
static_assert(in_range<float, 0.0f, 1.0f>(0.5f), "doesn't work")
但是,这不起作用,因此我默认以这种方式创建函数。
template<class T>
std::function<bool(T)> in_range(T min, T max) {
auto test = [min, max](T val) {
return (val >= min && val <= max);
};
return test;
}
assert(in_range<float>(0.0f, 1.0f)(0.5f))
有没有办法以第一个函数的形式编写更多函数,因此我不依赖于运行时生成的
std::function
和lambda? 最佳答案
浮点数aren't allowed as template non-type parameters,时,您必须将其作为实际函数参数而不是模板参数。
如果您想要一个仅接受一个参数的函数,则可以通过直接返回lambda来避免std::function
的开销。如果我们使用的是C++ 14,则可以使其返回auto
:
template<class T>
auto in_range(T min, T max) { // Note: could be `constexpr` in C++17
return [min, max](T val) {
return (val >= min && val <= max);
};
}
但是,由于使用的是C++ 11,因此必须手动写出可调用类型:
template <typename T>
class InRange {
public:
constexpr InRange(T min, T max)
: min(std::move(min))
, max(std::move(max))
{}
constexpr bool operator()(T const& val) const {
return (val >= min && val <= max);
}
private:
T min;
T max;
};
template<class T>
constexpr InRange<T> in_range(T min, T max) {
return InRange<T>(std::move(min), std::move(max));
}