在constexpr上下文中使用std::optional赋值运算符

9

我对 std::optional 感到困惑。根据文档,它不应该有一个 constexpr 赋值运算符。

然而,在 gcc-8.1 中,当我尝试这个片段时,它可以编译并正常工作:

constexpr std::optional<int> foo() {
    std::optional<int> bar = 3;
    bar = 1337;
    return bar;
}

constexpr auto z = foo();

Is there something I am missing?


constexpr auto z = foo() 也能编译吗? - Evg
@Evgeny 是的,它确实可以,在更复杂的情境下也能够运作... - ProXicT
@Evgeny 是的,现在就可以看到:https://godbolt.org/z/Y11f6k - Richard Critten
1
请参阅P0602。虽然它尚未应用于标准,但一旦应用,它将使赋值操作成为constexpr。(并且预计会追溯到C++17。) - cpplearner
@cpplearner 啊,这就解释了很多问题!请把它作为一个答案发布,我会接受它,因为那是正确的。 - ProXicT
1个回答

5
似乎这是gcc的一个bug。我刚刚尝试了clang-6.0,编译失败并出现了预期的错误。此外,标准中没有提到赋值运算符的任何constexpr重载,因此我将向gcc bugtracker报告此bug。 链接至bug报告

编辑:

事实证明这不是gcc的一个bug,而是标准中的一个错误:

我不明白在当前c++17标准没有指定任何constexpr赋值运算符的情况下,代码片段如何能在constexpr上下文中工作。

没错,但是标准有问题。

所有实现都将赋值运算符定义为默认值,因此编译器使其成为constexpr。

实际上,P0602R3提案是相关的,因为它将要求实现将运算符定义为默认值(以便为平凡), 因此编译器总是会为std::optional使其成为constexpr。

我已经向标准委员会提出了这个问题。

您可以在错误报告中阅读更多信息。


不,它在clang-6.0上也不会失败:https://wandbox.org/permlink/o7gn4bGMdazVGqUB - Andriy Tylychko
不过VS2017也不行。 - Andriy Tylychko
我在VS中检查了<optional>,是的,operator=不是constexpr,所以我猜它根本没有参与其中。难道它被优化掉了吗? - Andriy Tylychko
1
@AndriyTylychko 我不确定,我已经尝试使用 -std=c++17 -Wall -Wextra -pedantic -O0 -g -fno-elide-constructors 进行编译,但编译仍然成功。 - ProXicT
3
我已经发布了这个漏洞报告,我们将看看开发人员对此有何回应。 - ProXicT
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接