【问题标题】:static_assert within templated class constructor模板类构造函数中的 static_assert
【发布时间】:2021-06-14 11:25:12
【问题描述】:

我正在尝试创建一个由 std::initializer_list 初始化的示例数组类。我想在编译时检查初始化列表的大小是否不大于数组的大小。由于静态断言只能计算 constexpr,因此这段代码不会被编译。

#include<initializer_list>
#include<cstddef>

template <typename T , size_t _size>
class array
{

    private:
    T arr[_size];

    public:
    array()
    {
    }

    array(std::initializer_list<T> arrList)
    {
        static_assert(_size>arrList.size(),"too many initializers"); // error: non-constant condition for static assertion

    }

    ~array()
    {
    }

};

int main()
{
    array<int,4> arr = {1,2,3,4,5}; 


    return 0;
}

std::array 已经有了这个功能,但是我在头文件中找不到它的实现。

#include<array>

int main()
{
    std::array<int,5> arr= {1,2,3,4,5,6}; // error: too many initializers for ‘std::array<int, 5>’
    return 0;
    
}

【问题讨论】:

  • 对于array,它没有明确实现。 array 使用聚合初始化,编译器负责处理,而不是 STL。

标签: c++ arrays stl initializer-list


【解决方案1】:

std::initializer_list 不能这样做,arrList.size() 不能在常量表达式中使用,尽管它的 size() 成员函数被声明为 constexpr。看看this question

std::array 使用aggregate initialization,它没有采用std::initializer_list 的构造函数。这就是std::array 通常是implemented

template<typename T, std::size_t size>
struct array {
    T arr[size];
    /* member functions */
};

或者(调用构造函数的语法略有不同),您可以创建一个通过引用获取数组的构造函数:

template<typename T, std::size_t size>
class array {
public:
    template<std::size_t s>
    array(const T(& a)[s]) {
        static_assert(s <= size, "too many initializers");
    }
private:
    T arr[size];
};

然后

array<int, 4> arr({1, 2, 3, 4, 5}); // error: static_assert failed due to requirement
                                    // '5UL <= 4UL' "too many initializers"

由于static_assert,将无法编译。但是,您需要在 array 构造函数中使用一些技巧来执行 arr 数据成员的实际初始化(您不能这样做 arr(a))。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    相关资源
    最近更新 更多