为什么引用不能与编译时函数一起使用? [英] Why references can't be used with compile time functions?

查看:65
本文介绍了为什么引用不能与编译时函数一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个摘要.

第一段代码:

#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):

[expr.const]/2 :

表达式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;

...

[expr.const]/6 :

常量表达式是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆