通过引用调用`constexpr`成员函数-clang vs gcc

问题描述 投票:1回答:1

请考虑以下示例(片段(0)):

struct X
{
    constexpr int get() const { return 0; }
};

void foo(const X& x)
{
    constexpr int i = x.get();
}

int main()
{
    foo(X{});
}

上面的示例使用g++之前的所有g++ 10.x版本进行编译,而从未在clang++下进行编译。错误消息是:

error: 'x' is not a constant expression
    8 |     constexpr int i = x.get();
      |

live example on godbolt.org

错误的类型是有道理的,因为x从来不是foo主体中的常量表达式,但是:

  • [X::get()被标记为constexpr,它不取决于x的状态;

  • const X&更改为const X使代码可以在每个编译器中进行编译(on godbolt.org) 代码段(1)


当我将X::get()标记为static(on godbolt.org) 片段(2))时,它变得更加有趣。进行此更改后,g++的所有测试版本(包括主干)都将编译,而clang++仍然始终无法编译。

所以,我的问题:

  • g++ 9.x接受代码段(0)正确吗?

  • 所有编译器是否都正确接受snippet(1)?如果是这样,为什么引用很重要?

  • g++ 9.xg++ trunk接受代码段(2)正确吗?

c++ c++17 language-lawyer constexpr c++20
1个回答
0
投票

Gcc 9.x在这里是错误的。

使用constexpr int i = x.get();,您需要在编译时确定i的值。

但是x是运行时参数-您可以在运行时使用任何参数调用foo;因此,在编译时可能无法知道x.get()返回的值。因此,在编译时不可能知道i的值。

© www.soinside.com 2019 - 2024. All rights reserved.