gpt4 book ai didi

c++ - constexpr 函数调用无法编译

转载 作者:行者123 更新时间:2023-12-04 11:34:49 25 4
gpt4 key购买 nike

为什么下面的代码不能编译?

#include <stdint.h>
#include <array>

class A
{
struct Helper
{
static constexpr uint64_t p2(uint8_t n)
{
return static_cast<uint64_t>(1) << n;
}
};

using DenomArray = std::array<uint64_t, Helper::p2(5)>;
};
使用 GCC 我得到:
error: 'static constexpr uint64_t A::Helper::p2(uint8_t)' called in a constant expression before its definition is complete
我的理解是 p2应该定义函数,因为 Helper类已完全编译。
为 x86 和 GCC 12 尝试了 MSVC 编译器版本 19.29.30040。
编辑 1:
模板和非模板类的行为不同。例如下面的代码编译:
template <class T>
class A
{
private:

struct Helper
{
static constexpr T p2(uint8_t n)
{
return static_cast<T>(1) << n;
}
};

using DenomArray = std::array<T, Helper::p2(5)>;
};

using IntA = A<uint64_t>;

最佳答案

您定义的地方 DenomArray在哪里A::Helper尚未完全定义,这使得 A::Helper::p2(5)非常量表达式。
有趣的是,制作A一个模板解决了这个问题——这可能是一个语言缺陷——见这里:http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1626
更正式的:https://eel.is/c++draft/temp.arg.nontype#2

A template-argument for a non-type template-parameter shall be aconverted constant expression ([expr.const]) of the type of thetemplate-parameter.


然后 https://eel.is/c++draft/expr.const#5 :

An expression E is a core constant expression unless the evaluation ofE, following the rules of the abstract machine ([intro.execution]),would evaluate one of the following:


现在到您编码违反的部分: https://eel.is/c++draft/expr.const#5.3

(5.3) an invocation of an undefined constexpr function;


为什么它未定义? - 因为它在被视为非完整上下文的上下文中使用:
https://eel.is/c++draft/class#mem.general-7

A complete-class context of a class (template) is a(7.1) function body ([dcl.fct.def.general]),(7.2) default argument ([dcl.fct.default]),(7.3) default template argument ([temp.param]),(7.4) noexcept-specifier ([except.spec]), or (7.5) default memberinitializer


所以它不是说 struct的 body 是一个完整的类上下文。您可以放置​​您的 using在函数体内,它会编译:
class A
{
struct Helper
{
static constexpr uint64_t p2(uint8_t n)
{
return static_cast<uint64_t>(1) << n;
}
};
void ff() {
using DenomArray = std::array<uint64_t, Helper::p2(5)>;
}
};
[编辑]
另外,请参见此处: https://coliru.stacked-crooked.com/a/6536fdbe1ded1d01 , clang 错误与 gcc 不同,因为它说 Helper::p2(5)是非 constexpr :

error: non-type template argument is not a constant expression


这就是我上面解释的。

关于c++ - constexpr 函数调用无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68777610/

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