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

标签 c++ c++20

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

相关文章:

C++ 堆/栈说明

C++20 概念 : requires expression and perfect forwarding

c++ - 将模板函数作为参数传递给另一个函数

c++ - 为什么 `std::remove_cv<_Iter>::type` 不是一个类型?

c++ - OSX Lion 上 curses.h 的问题

c++ - 为什么 #ifndef 在这种情况下不起作用?

c++ - 为什么条件中定义的变量不能用参数构造?

c++ - 如何对带有约束的模板类使用友元声明

C++20 概念 : multiple return type requirements?

c++ - 拆分 malloc 内存空间