You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20/23中consteval成员函数调用合法性:哪款编译器合规?

C++20/23中consteval成员函数调用的编译器行为正确性分析

测试代码

#include <cstddef>

template <size_t N>
class Foo {
    public:
        consteval size_t size() noexcept { return N; }

        size_t real_size() {
            return size() - 1;
        }
};

int main(int argc, char* argv[]) {
    Foo<5> foo;
    return foo.real_size();
}

不同编译器的编译结果

  • Clang 10与GCC 14.1:无错误、无警告编译通过
  • Clang 14至18.1版本:触发编译错误,错误信息如下:
<source>:9:20: error: call to consteval function 'Foo<5>::size' is not a constant expression
    9 |             return size() - 1;
      |                    ^
<source>:15:16: note: in instantiation of member function 'Foo<5>::real_size' requested here
   15 |     return foo.real_size();
      |                ^
<source>:9:20: note: implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function
    9 |             return size() - 1;
      |                    ^

问题与解答

问题

依据C20与C23标准,哪款编译器的行为是正确的?原因是什么?

解答

正确的行为是Clang 14-18.1报错,GCC 14.1和Clang 10的编译通过属于不符合标准的宽松实现,原因如下:

  1. consteval函数的调用要求:C++标准规定,consteval函数必须在常量表达式语境中调用,且调用结果必须是常量表达式。
  2. this指针的语境限制:size()是非静态consteval成员函数,调用时会隐式传递this指针。而real_size()是普通成员函数,不属于常量表达式语境——即使Foo<5>是模板实例化类型,this指向的对象是运行时创建的,此时调用consteval函数时,this的值无法在编译期确定,不符合常量表达式的要求。
  3. 标准条款依据:标准明确指出,隐式使用this指针的consteval成员函数调用,仅当整个调用处于常量表达式语境时才被允许。非常量表达式语境下的此类调用属于非法行为。

Clang 14及后续版本修正了早期实现的错误,严格遵循标准;而GCC 14.1和Clang 10未正确执行该检查,属于非标准的宽松处理。

内容的提问来源于stack exchange,提问作者HCSF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:22:43