gpt4 book ai didi

c++ - 通过 CRTP 的基类引用访问派生类的 constexpr 成员变量

转载 作者:行者123 更新时间:2023-12-04 15:08:51 26 4
gpt4 key购买 nike

尝试通过 CRTP 的基类引用访问派生类的 constexpr 成员变量时遇到错误;

template <typename Der>
struct Base
{
constexpr std::size_t getsize()
{
constexpr const auto &b = static_cast<Der*>(this)->arr;
return b.size();
//return static_cast<Der*>(this)->arr.size(); // this works
}
};

struct Derived : Base<Derived>
{
static constexpr std::array<int, 10> arr = {};
};

int main(){
Derived d;
return d.getsize();
}

错误:

<source>:11:31: error: constexpr variable 'b' must be initialized by a constant expression
constexpr const auto &b = static_cast<Der*>(this)->arr;
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:24:14: note: in instantiation of member function 'Base<Derived>::getsize' requested here
return d.getsize();
^
<source>:11:53: note: use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function
constexpr const auto &b = static_cast<Der*>(this)->arr;
^
1 error generated.
Compiler returned: 1

更新事实证明,删除引用作品中的 constexpr。我想了解为什么会这样?

        auto &b = static_cast<Der*>(this)->arr;
return b.size();

最佳答案

非正式地,您应该想象有一个规则 constexpr函数内定义的变量 需要由表达式初始化,该表达式始终 是常量表达式,无论函数在何种情况下被调用。特别是,您始终可以执行以下操作:

Base<Derived> b;
b.getSize();

在这种情况下static_cast<Der*>(this)->arr不是常量表达式,因为它实际上是 UB。由于这样的事情可能性,您的函数根本无法编译,即使您可能永远不会以这种方式调用它。

您违反的实际规则是 [expr.const]/5.1。常量表达式 E 可能无法计算 this , 除非它是通过(直接或间接)调用某个成员函数,其中对 this 的求值发生。特别是,这意味着如果我们有这样的代码:

// namespace scope
struct S {
constexpr const S* get_self() {
const S* result = this;
return result;
}
};
constexpr S s;
constexpr const S* sp = s.get_self();

在这里,s.get_self()是常量表达式,因为访问this只发生在 get_self() 内函数,它是 s.get_self() 评估的一部分.但是我们不能制作result constexpr ,因为如果是这样,我们就不再需要“计算”封闭函数了;初始化步骤本身必须符合常量表达式的条件,但事实并非如此,因为可以访问 this。现在是“光秃秃的”。

对于您的代码,这意味着 getsize()实际上可能会返回一个常量表达式(对于那些不触发 UB 的调用,如上所述)但是 b无法制作constexpr .

关于c++ - 通过 CRTP 的基类引用访问派生类的 constexpr 成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65587188/

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