是否可以验证传递给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
功能。
答案 0 :(得分:9)
虽然size()
的{{1}}可以评估为std::initializer_list<T>
constexpr
成员在size()
内的行为不会像constexpr
} function:有意的是,对象在constexpr
表达式中只表现为constexpr
,而不是在其他地方。
例如:
constexpr
在第一种情况(1)中,假定产生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)
// ...
}
的值取决于constexpr
开始之前创建的数据。因此,它不会评估为constexpr
。在第二种情况(2)中,数据在constexpr
内定义,因此结果可以变为constexpr
。
我没有参与导致这种设计的讨论,但似乎是因为希望阻止constexpr
参数改变constexpr
函数的结果类型:如果值是函数定义中的constexpr
,它们在返回值中也可以是constexpr
,因此可以在返回类型中用作模板参数。这会导致constexpr
函数的值不同,从而产生不同的类型。到目前为止,只能通过改变函数的参数类型和/或通过改变函数的参数数量来获得不同的返回类型。