简体   繁体   English

模板化 class 构造函数中的 static_assert

[英]static_assert within templated class constructor

I am trying to create a sample array class which is initialiszed by a std::initializer_list.我正在尝试创建一个由 std::initializer_list 初始化的示例数组 class。 I would like to check if the size of the initializer list is not more than the size of the array during compile time.我想在编译时检查初始化列表的大小是否不大于数组的大小。 Since static assert can only evaluate constexpr, this code is not getting compiled.由于 static 断言只能评估 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 already has this functionality, but i couldnt find its implementation in header file. std::array 已经具有此功能,但在 header 文件中找不到它的实现。

#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;
    
}

You can't do it with std::initializer_list , arrList.size() cannot be used in a constant expression, although its size() member function is declared as constexpr .你不能用std::initializer_list来做到这一点, arrList.size()不能用于常量表达式,尽管它的size()成员 function 被声明为constexpr Take a look at this question .看看这个问题

std::array uses aggregate initialization , it doesn't have a constructor that takes an std::initializer_list . std::array使用聚合初始化,它没有采用std::initializer_list的构造函数。 This is how std::array is typically implemented :这就是std::array通常的实现方式:

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

Alternatively (with slightly different syntax for calling a constructor), you can make a constructor that takes an array by reference:或者(调用构造函数的语法略有不同),您可以创建一个通过引用获取数组的构造函数:

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];
};

Then然后

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

will fail to compile thanks to static_assert .由于static_assert将无法编译。 However, you'll need some tricks inside the array constructor to perform the actual initialization of arr data member (you can't do arr(a) ).但是,您需要在array构造函数中使用一些技巧来执行arr数据成员的实际初始化(您不能这样做arr(a) )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM