为什么引用不能与编译时函数一起使用? [英] Why references can't be used with compile time functions?
问题描述
我有两个摘要.
第一段代码:
#include <string>
template <typename T>
constexpr bool foo(T&&) {
return false;
}
int main() {
std::string a;
if constexpr (foo(a)) {
}
}
第二个片段:
#include <string>
template <typename T>
constexpr bool foo(T&&) {
return false;
}
int main() {
std::string a;
std::string& x = a;
if constexpr (foo(x)) {
}
}
第一个编译,但是第二个不编译(错误消息:错误:'x'的值不能在常量表达式中使用.为什么?为什么 a
在常量表达式中可用,而 x
不可用吗?
The first one compiles, but the second one does not compile (error message: error: the value of ‘x’ is not usable in a constant expression. Why? Why a
is usable in a constant expression and x
is not?
该命令,用于编译 g ++ -std = c ++ 17 main.cpp
.
推荐答案
因为通常,常量表达式无法计算引用具有自动存储持续时间的对象的引用.在这里,我的意思是通过确定 身份 对象,不确定对象的值.因此,即使您的示例中甚至不需要对象 a
的值(即未应用左值到右值转换), foo(x)
仍不是常量表达.
Because usually a constant expression cannot evaluate a reference that refers to an object with automatic storage duration. Here I mean "evaluate" by determining the identity of the object, not by determining the value of the object. So even the value of the object a
is not required in your example (i.e. no lvalue-to-rvalue conversion is applied), foo(x)
is still not a constant expression.
注意 foo(a)
不评估任何引用.尽管 foo
的参数是引用,但不会将其评估为表达式.实际上,例如,即使对其进行了评估,
Note foo(a)
does not evaluate any reference. Although the parameter of foo
is a reference, it is not evaluated as an expression. In fact, even if it was evaluated, for example,
template <typename T>
constexpr bool foo(T&& t) {
t;
return false;
}
foo(a)
仍然是一个常量表达式.此类情况是例外,因为参考 t
在 foo(a)
的评估之内初始化了.
foo(a)
is still a constant expression. Such cases are exceptions as the reference t
is initialized within the evaluation of foo(a)
.
标准中的相关部分(无关的部分被我删除了):
Related part in the standard (irrelevant part is elided by me):
表达式e是核心常量表达式,除非按照抽象机的规则对e的求值将对以下表达式之一求值:
An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:
-
...
...
一个id表达式,它引用引用类型的变量或数据成员,除非引用具有前面的初始化,并且其中一个都为
an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either
-
使用常量表达式或
it is initialized with a constant expression or
其寿命始于e的评估;
its lifetime began within the evaluation of e;
...
常量表达式是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), ... 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.
这篇关于为什么引用不能与编译时函数一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!