gpt4 book ai didi

c++ - 非 constexpr 变量成员调用在具有条件的 constexpr 类成员函数中编译 - 为什么?

转载 作者:行者123 更新时间:2023-12-03 07:00:33 24 4
gpt4 key购买 nike

#include <variant>

struct S {
constexpr auto f() -> void {
// deleting the next line creates an error
if(std::holds_alternative<int>(m_var))
m_var.emplace<double>(5.0);
}
std::variant<int, double> m_var;
};

int main() {
return 0;
}

std::variant有一个非 constexpr成员函数 emplace() .一般来说,您不能在 constexpr 中使用它职能。但是,如果您通过使用 std::holds_alternative() 的条件包围该调用,则可以在那种类型上。还有其他 constexpr 函数,只要它们是该类中的成员函数。
我很难理解发生了什么。我的第一 react 是说这是一个错误。该条件不可能比根本没有条件更 constexpr。但也许这为时过早。任何人都可以对此有所了解吗?为什么会这样 emplace()不是 constexpr 而是(相等类型)赋值?
编辑:也许要扩展一点:一种猜测是所涉及变体的构造函数和析构函数可能是非constexpr,这就是为什么 emplace等不是。但有趣的是,即使您明确滥用非 constexpr 构造函数,您也可以使用这样的条件将函数编译为 constexpr。这使该论点无效。
神箭: here .

最佳答案

您实际上不需要深入研究 std::variant对此进行推理。这主要是关于常量表达式的工作原理。 constexpr函数必须以允许在常量表达式中求值的方式定义。对于某些参数,我们是否遇到无法出现在常量表达式中的内容并不重要,只要对于其他参数我们获得有效的常量表达式即可。标准中明确提到了这一点,例如

[dcl.constexpr]

5 For a constexpr function or constexpr constructor that isneither defaulted nor a template, if no argument values exist suchthat an invocation of the function or constructor could be anevaluated subexpression of a core constant expression, or, for aconstructor, a constant initializer for some object([basic.start.static]), the program is ill-formed, no diagnosticrequired. [ Example:

constexpr int f(bool b)
{ return b ? throw 0 : 0; } // OK
constexpr int f() { return f(true); } // ill-formed, no diagnostic required

struct B {
constexpr B(int x) : i(0) { } // x is unused
int i;
};

int global;

struct D : B {
constexpr D() : B(global) { } // ill-formed, no diagnostic required
// lvalue-to-rvalue conversion on non-constant global
};

 — end example ]


看看如何 f(bool)是有效的 constexpr功能?即使 throw表达式不能在常量表达式中求值,它仍然可以出现在 constexpr 中。功能。只要持续评估没有达到它就没有问题。
如果没有 constexpr 的参数集函数可以用在常量表达式中,程序格式错误。这种格式错误的程序不需要诊断,因为仅从函数定义中检查这种情况通常是难以处理的。然而,它是无效的 C++,即使编译器没有引发错误。但在某些情况下,它可以被检查,因此编译器可能有义务提出诊断。
您的 f 没有 一个条件属于这种格式错误的结构。不管怎样 f被调用,它的执行将导致调用 emplace , 不能出现在常量表达式中。但是它很容易检测到,因此您的编译器会告诉您这是一个问题。
带有条件的第二个版本不再调用 emplace无条件。现在是有条件的。条件本身依赖于 constexpr函数,所以它不会立即格式错误。一切都取决于函数的参数(包括 this)。所以它不会立即引发错误。

关于c++ - 非 constexpr 变量成员调用在具有条件的 constexpr 类成员函数中编译 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64371808/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com