如何static_assert,初始化列表是一定大小
How to static_assert that an initializer list is a certain size
是否可以验证正在传递给constexpr
构造函数的初始化列表是一定大小吗?还是只有在运行时才能做?
这是这个想法,但它不起作用:
struct group
{
constexpr group(
std::initializer_list<std::initializer_list<UINT const> const> groups
)
{
static_assert(each_list_size_greater_than_1(groups.begin(), groups.end()));
}
constexpr static bool each_list_size_greater_than_1(
std::initializer_list<std::initializer_list<UINT const> const>::const_iterator const begin
, std::initializer_list<std::initializer_list<UINT const> const>::const_iterator const end)
{
return begin == end || begin->size() > 1 && each_list_size_greater_than_1(begin + 1, end);
}
};
我已经查看了VS2015的std::initializer_list
实现,begin()
,end()
和size()
都是constexpr
功能。
尽管std::initializer_list<T>
的size()
可以评估constexpr
size()
成员在constexpr
函数中不会像constexpr
一样行为:这是故意的,只有对象像constexpr
表达式中的constexpr
一样行为他们被介绍的地方,但没有其他地方。
例如:
constexpr get_size(std::initializer_list<int> list) {
constexpr std::size_t csize = list.size(); // ERROR (1)
std::size_t size = list.size(); // OK
return size;
}
int main() {
constexpr std::size_t csize = get_size(std::initializer_list<int>{ 1, 2, 3 }); // OK (2)
// ...
}
在第一种情况下(1)假定产生constexpr
的值取决于constexpr
启动之前创建的数据。结果,它没有评估constexpr
。在第二种情况(2)中,数据是在constexpr
中定义的,因此,结果可以成为constexpr
。
我还没有参与导致该设计的讨论的一部分,但是看来这是由于防止constexpr
参数更改constexpr
函数的结果类型的愿望而动机:如果值在功能定义中为constexpr
s,则它们返回值也将是constexpr
s,因此可以用作返回类型中的模板参数。这将导致constexpr
功能产生不同类型的不同值。到目前为止,您只能通过更改函数的参数类型和/或通过更改函数的参数数量来获得其他返回类型。
相关文章:
- 复制列表初始化的隐式转换的等级是多少
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- C++11 中的混合列表初始化
- 我可以列表初始化 std::vector 并完美转发元素吗?
- 无法在声明时使用初始值设定项列表初始化常量字符*/字符串数组的向量
- C++20 从括号中的值列表初始化聚合,不支持内部数组
- 如何在向量列表初始化时避免对象复制以及如何延长临时的生存期
- 默认参数和空列表初始化
- 如何在列表初始化中放置额外的语句?
- C++列表初始化允许多个用户定义的转换
- 列表初始化是否将原子初始化为零
- 使用可变模板列表初始化数组,并放置new
- 使用整数初始化列表初始化长双精度的向量
- 直接列表初始化的自动规则
- 使用初始化列表初始化unique_ptr的容器,继续
- 如何修复"非聚合无法使用初始值设定项列表初始化" <map>
- 直接列表初始化和复制列表初始化之间的差异
- 为什么我可以在不使用赋值运算符的情况下使用列表初始化普通数组
- C++ - 使用类中的初始值设定项列表初始化动态集