【问题标题】:MSVC fails to compile when using a constexpr initializer_list constructor使用 constexpr initializer_list 构造函数时,MSVC 无法编译
【发布时间】:2017-08-11 08:11:12
【问题描述】:

为什么 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, "!!");

我得到的错误是:

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

initializer_list 的实现将所有方法标记为constexpr,看起来对我来说应该没问题...也许只是编译器问题?

【问题讨论】:

    标签: c++ c++11 visual-c++ constexpr initializer-list


    【解决方案1】:

    TL;DR:这是一个 编译器 标准问题,因为您的代码可以很好地编译 gcc 6.3.1clang 3.9.1 都可以编译不过你的代码。


    在 C++11 中,没有一个方法被标记为 constexpr,因此您不能在 static_assert 中使用它。

    您必须注意,Visual Studio 2015 没有完整的constexpr 支持。请参阅文章中的the C++ 14 Core Language Features 表。它只实现了std::initializer_list 的C++11 版本,没有任何constexpr 函数。

    小更新:标准中的错误措辞似乎会导致非常量的std::initializer_list

    来自第 18.9.2 节(强调我的):

    initializer_list&lt;E&gt; 类型的对象提供对const E 类型对象数组的访问。 [注意:一对指针或一个指针加上一个长度将是initializer_list 的明显表示。 initializer_list 用于实现 8.5.4 中指定的初始化列表。复制初始值设定项列表不会复制底层元素。
    ——尾注]

    因此,initializer_list 的实现的私有成员不需要是非易失文字类型;然而,因为他们提到他们相信一对指针或一个指针和一个长度将是“明显的表示”,他们可能没有考虑到有人可能会在 initializer_list 的成员中放入非文字的东西。

    (从this 答案中无耻地复制。)它更深入一点,关于为什么你不能在constexpr 上下文中使用std::initializer_list

    这已在 Visual Studio 2017 中“修复”。

    【讨论】:

    • 我正在编译的 VS2015 &lt;initializer_list&gt; 确实在所有方法上都有 constexpr,这就是为什么我很惊讶它没有工作。
    • @ManuEvans 这很奇怪。经过调查,我发现原因是标准中的一个错误措辞,这似乎在 VS 2015 的实施中没有得到修复。见编辑:)
    • @Rakete1111 - 已确认。 ' 用 VS2017 编译
    • @Jeff 感谢您的信息! :)
    • @Jeff 这很有趣,我试图切换到 2017,但遇到了一个更大的问题:stackoverflow.com/questions/42917099/…
    【解决方案2】:

    尝试设置Conformance mode,它会消除编译错误。

    【讨论】:

    • 不适合我。但是关闭 SDL 检查是可行的。
    猜你喜欢
    • 1970-01-01
    • 2020-02-10
    • 2021-02-12
    • 2023-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    相关资源
    最近更新 更多