gpt4 book ai didi

c++ - 检查和越界的概念

转载 作者:行者123 更新时间:2023-12-05 03:17:45 25 4
gpt4 key购买 nike

我正在尝试定义一个 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/

25 4 0
文章推荐: c# - 如何在 Expression 中转换可以是对象或 List 的 TResult?