Man*_*ans 3 c++ initializer-list visual-c++ constexpr c++11
为什么Microsoft Visual C++在编译以下代码时失败?:
template <typename T>
struct slice
{
size_t length;
T *ptr;
constexpr slice(std::initializer_list<T> list)
: length(list.size()), ptr(list.begin()) {}
};
static_assert(slice<const int>({ 1, 2, 3 }).length == 3, "!!");
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
1>test.cpp(12): error C2131: expression did not evaluate to a constant
1> visual studio 14.0\vc\include\initializer_list(50): note: failure was caused by an undefined arithmetic operation
Run Code Online (Sandbox Code Playgroud)
initializer_list所有方法的实现都标记了constexpr,看起来它对我来说应该没问题......也许它只是一个编译器问题?
TL; DR:这是一个编译器 标准问题, 因为你的代码编译得很好 gcc 6.3.1和clang 3.9.1都编译了你的代码.
在C++ 11中,没有标记其中一个方法constexpr,因此您无法在其中使用它static_assert.
您必须注意Visual Studio 2015没有完全constexpr支持.请参阅本文中的C++ 14核心语言功能
表.它只有C++ 11版本的std::initializer_list实现,它没有任何constexpr功能.
小更新:看起来标准中的错误措辞会导致非常数std::initializer_list:
从§18.9.2(强调我的):
类型的对象
initializer_list<E>提供对类型对象数组的访问const E.[注意:一对指针或一个指针加上一个长度将是明显的表示initializer_list.initializer_list用于实现8.5.4中指定的初始化列表.复制初始化列表不会复制基础元素.
- 尾注]因此,不要求实现的私有成员是
initializer_list非易失性文字类型; 然而,因为他们提到他们相信一对指针或一个指针和一个长度将是"明显的代表",他们可能不会认为有人可能会把非文字的东西放在其中initializer_list.
(从这个答案无耻地复制.)它更深入,关于为什么你不能std::initializer_list在constexpr上下文中使用.
这已在Visual Studio 2017中"修复".
| 归档时间: |
|
| 查看次数: |
721 次 |
| 最近记录: |