gpt4 book ai didi

c++ - 关于在需要常量表达式的上下文中使用的泛左值常量表达式的问题

转载 作者:行者123 更新时间:2023-12-01 14:57:38 25 4
gpt4 key购买 nike

#include <iostream>
constexpr int func2(int const& id){
return id;
}
template<int v>
struct Test{

};
int main(){
const int v = 0;
Test<func2(v)> c;
}
考虑上面的代码,我只是不明白为什么代码格式正确。我的观点是名称 v在计算表达式 func2 时用作泛左值,因为 func2的参数是引用类型, v需要绑定(bind)到 id-expression id .所以我们看一下glvalue常量表达式的要求,这里有关于它的引用。

A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints.


我们忽略了prvalue的情况,因为这里 v用作glvalue。
实体是常量表达式的允许结果是:

An entity is a permitted result of a constant expression if it is an object with static storage duration that is either not a temporary object or is a temporary object whose value satisfies the above constraints, or it is a function.


在我的程序部分, const int v = 0;没有 静态存储时长 ,它只是具有自动存储期限。所以在评估表达式时 func2(v)判断是否为常量表达式,首先, v必须是一个glvalue核心常量表达式,它引用一个实体,它是一个常量表达式的允许结果,因此,为什么程序在这里格式正确?如果我丢失了任何重要的引用,请纠正我。

最佳答案

We ignore the case of prvalue, because here v is used as a glvalue



是吗?这是来自 cppreference 的示例:
void test() {
static const int a = std::random_device{}();
constexpr const int& ra = a; // OK: a is a glvalue constant expression
constexpr int ia = a; // Error: a is not a prvalue constant expression

const int b = 42;
constexpr const int& rb = b; // Error: b is not a glvalue constant expression
constexpr int ib = b; // OK: b is a prvalue constant expression
}

是的, const int b = 42这里比较奇怪,因为从技术上讲,你可以绑定(bind) bconst int& , const_cast const并为其分配运行时值。然而,考虑到什么是 integral constant expressionwhat are the requirements of a const object这很有意义:

Integral constant expression is an expression of integral or unscoped enumeration type implicitly converted to a prvalue, where the converted expression is a core constant expression. If an expression of class type is used where an integral constant expression is expected, the expression is contextually implicitly converted to an integral or unscoped enumeration type.



变量 b确实看起来像是可以隐式转换为纯右值常量表达式的东西,因为它基本上用作文字 42 的别名在这种情况下,整数文字根据定义是纯右值。

现在对于有问题的部分 - 这个:

const object - an object whose type is const-qualified, or a non-mutable subobject of a const object. Such object cannot be modified: attempt to do so directly is a compile-time error, and attempt to do so indirectly (e.g., by modifying the const object through a reference or pointer to non-const type) results in undefined behavior.



和:

A core constant expression is any expression whose evaluation would not evaluate any one of the following:

...

an expression whose evaluation leads to any form of core language undefined behavior (including signed integer overflow, division by zero, pointer arithmetic outside array bounds, etc). Whether standard library undefined behavior is detected is unspecified.



意味着一旦你开始用它做有趣的事情 b ,你可以期待任何事情发生。例如,这是我在最新的 MSVC 中尝试对您的代码执行的操作,并打开了所有标准一致性选项:
#include <iostream>
#include <random>

constexpr int func2(int const& id) {
return id;
}

template<int v>
struct Test {

long array[v];

};

int main() {

const int v = 0;
const int& ref = v;

const_cast<int&>(ref) = std::random_device()() % std::numeric_limits<int>::max();


Test<func2(v)> c;

return 0;

}

打开语言扩展后,我得到了 C4200: nonstandard extension used : zero-sized array in struct/union警告。关闭它们后,程序将无法编译。当我删除 array结构的一部分,它再次开始编译。

关于c++ - 关于在需要常量表达式的上下文中使用的泛左值常量表达式的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61926165/

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