类模板中的 Constexpr 成员函数

2024-04-08

以下代码无法编译:

// template<class>
struct S {
    int g() const {
        return 0;
    }

    constexpr int f() const {
        return g();
    }
};

int main()
{
    S /*<int>*/ s;
    auto z = s.f();
}

例如,海湾合作委员会抱怨道:错误:调用非 constexpr 函数‘int S::g() const’。这是完全合理的。但如果我转身S到模板中,代码编译(使用 MSVC 15.3、GCC 7.1.0、clang 4.0.1 检查)。

为什么?做常量表达式类模板中有什么特殊含义吗?

据我了解,这段代码是不正确的,但标准并不要求编译器产生错误(为什么?)。


根据 [dcl.constexpr]

constexpr 函数的定义应满足以下约束:
...
用于初始化返回值(6.6.3、8.5)的每个构造函数调用和隐式转换应为 常量表达式中允许的其中之一

致电g()不允许出现在常量表达式中。根据 [expr.const]:

A 条件表达式 is a 核心常量表达式除非它涉及以下其中一项作为潜在的 评估子表达式...:
— 调用除 [...] a 之外的函数constexpr功能

看起来有些编译器可能允许你做你正在做的事情,因为z未声明constexpr因此在编译时不需要知道该值。如果您将代码更改为

constexpr auto z = s.f();

你会注意到所有这些编译器都将继续执行 barf,无论是否使用模板。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类模板中的 Constexpr 成员函数 的相关文章

随机推荐