我正在尝试定义一个 C++20 概念
,它强制实现者检查越界。
template <size_t Num>
concept IsInBounds = requires (const size_t idx) {
requires idx >= Num;
};
因此,对于我在自定义容器中使用的返回对其中元素的非常量引用的方法,我想检查该概念是否需要的索引超出范围。
auto mut_ref_at(const size_t idx) const -> T(&) requires IsInBounds<N>
{
return (T&) array[idx];
}
这显然是行不通的:
error: substitution into constraint expression resulted in a non-constant expression
requires idx >= Num;
function parameter 'idx' with unknown value cannot be used in a constant expression
requires idx >= Num;
所以,如果我对概念有所了解,那么这个概念就是理解 requires (const size_t idx)
子句,其中我有一个参数 idx,正在替换参数 idx我的方法的
?
并且,存在某种方式将 mut_ref_at
方法的值 idx
限制为 T 数组 [N]
成员?
全类声明:
template <typename T, zero::size_t N>
class StackArray{
private:
T array[N];
public:
template <typename... InitValues>
StackArray(InitValues... init_values)
: array{ init_values... } {}
/**
* @brief delete the `new` operator, since the intended usage of
* the type is to be a wrapper over a C-style array.
*
* @return void*
*/
void* operator new(std::size_t) = delete;
/**
* @brief Returns a mut reference to the element at specified location `idx`,
* with bounds checking.
*
* @param idx a `size_t` value for specifiying the position of
* the element to retrieve.
* @return T& to the element at idx position
*/
constexpr auto mut_ref_at(const size_t idx) const -> T(&) requires IsInBounds<N>
{
return (T&) array[idx];
}
编辑:更改概念声明
最佳答案
如果要在编译时提供越界
检查,则必须通过模板参数提供索引。您应该依靠 std::size_t
值来提供客户端代码想要检索的索引,并且根据这个概念,索引将在模板实例化时确定。如果索引越界
,这将导致编译器拒绝编译。
您的代码将如下所示:
template <size_t I, size_t N>
concept IsInBounds = requires () {
requires I <= N;
};
您使用类模板参数 N
来确定数组容量。因此,您可以对照 N 检查 I。如果 I 大于 N,概念将失败,代码将无法编译。
你的方法看起来像:
template <size_t I>
constexpr T& mut_ref_at() requires IsInBounds<I, N>
{
return arr[I];
}
请注意,正如其他人指出的那样,转换为 (T&)
是丑陋且不必要的。尾随返回也很冗长,返回类型显然总是 T&
。
关于c++ - 检查和越界的概念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73985352/