c++ - VS2015中,{1,2,3}能转换成constexpr std::initializer_list<int>吗?

浏览:37日期:2023-04-02

问题描述

我看到vs2015中的std::initializer_list已经声明成constexpr了。那么

template<class T>constexpr bool assert_elementof(std::initializer_list<T> v, int N){ //static_assert(N == v.size(),'xxx'); return N == v.size();}int main(){ constexpr int v[] = { 1,2,3 }; static_assert(assert_elementof<int>(std::initializer_list<int>(v, v + sizeof(v) / sizeof(v[0])), 3), 'eee'); //static_assert(assert_elementof<int>({ 1,2,3 }, 3), 'eee'); return 0;}

我的是问题,为什么上面两处注释掉的代码不能在VS2015下编译通过?是我的代码有问题呢,还是VS2015的问题。

问题解答

回答1:

关于

static_assert(assert_elementof<int>({ 1,2,3 }, 3), 'eee');

由于static_assert的第一个参数必须是一个const表达式,对于constexpr bool assert_elementof(std::initializer_list<T> v, int N),只有当两个参数都是const的时候,他的返回值才是const。所以两个参数{ 1,2,3 }, 3都是常量,所以这一段没有问题。

关于

template<class T>constexpr bool assert_elementof(std::initializer_list<T> v, int N){ //static_assert(N == v.size(),'xxx'); return N == v.size();}

去掉那个注释为什么就不行了,因为N是一个变量,不是一个常量表达式,所以违反static_assert的要求:第一个参数必须是一个const表达式。

c++ primer里面有一段摘录如下:

constexpr int scale(int N) {return N * 2; }int main(){ int arr[scale(2)]; int i = 2; int arr2[scale(i)];//这里应该会报错,虽然G++不报错。 return 0;}

不报错的原因参考这里

回答2:

应该没问题,记得加头文件

#include <initializer_list>

相关文章: