引用评估和常量表达式
Reference evaluation and constant expression
struct test1 {
static constexpr int get() {
return 1;
}
};
struct test2 {
constexpr int get() const {
return 1;
}
};
template <class T>
int get(T&& t) {
if constexpr (t.get() == 1) {
return 1;
}
return 2;
}
int main() {
return get(test1{}) + get(test2{});
}
尝试使用 GCC-11.1 (-std=c++2a) 进行编译时,get
模板使用 test1
成功编译,但未使用 test2
。它们之间的唯一区别是 test2::get
是静态的。
显然,它不能用 test2
编译,因为 t
参数不是“核心常量表达式”,根据 7.7 expr.const(5.13):
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:
- an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization...
问题是当通过同一个引用访问的函数是静态的时,为什么它会编译。在这种情况下,引用不是“评估”的吗?是 GCC 错误还是标准中的某些措辞允许它?
常量表达式中对未知数的指针和引用直接格式错误 可能会 在 C++23 中解决,如果是这样,则作为缺陷早期语言版本的报告。
[...] when the function being accessed via the very same reference is static. Isn't the refence "evaluated" in this case? Is it a GCC bug or there's some wording in the Standard that allows it?
你的程序对于 static
的情况也是错误的,正如在下面的问答中详细回答的那样:
但是,EWG 认为这是 constexpr 规范中的一个缺陷,并建议 CWG 考虑通过 P2280R3 解决它(在常量表达式中使用未知指针和引用),针对 C++23,并作为 C++11 到 C++20 的 DR(缺陷报告)。
jfbastien commented on Feb 3, 2021
EWG saw this paper in today's telecon.
P2280 Using unknown references in constant expressions
The use cases presented in P2280 are problems in C++’s specification of constexpr, and we would like to fix these problems, ideally in C++23.
This should be a Defect Report against C++20, C++17, C++14, and C++11.
然而,最终决定权在尚未研究该问题的 CWG。
struct test1 {
static constexpr int get() {
return 1;
}
};
struct test2 {
constexpr int get() const {
return 1;
}
};
template <class T>
int get(T&& t) {
if constexpr (t.get() == 1) {
return 1;
}
return 2;
}
int main() {
return get(test1{}) + get(test2{});
}
尝试使用 GCC-11.1 (-std=c++2a) 进行编译时,get
模板使用 test1
成功编译,但未使用 test2
。它们之间的唯一区别是 test2::get
是静态的。
显然,它不能用 test2
编译,因为 t
参数不是“核心常量表达式”,根据 7.7 expr.const(5.13):
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:
- an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization...
问题是当通过同一个引用访问的函数是静态的时,为什么它会编译。在这种情况下,引用不是“评估”的吗?是 GCC 错误还是标准中的某些措辞允许它?
常量表达式中对未知数的指针和引用直接格式错误 可能会 在 C++23 中解决,如果是这样,则作为缺陷早期语言版本的报告。
[...] when the function being accessed via the very same reference is static. Isn't the refence "evaluated" in this case? Is it a GCC bug or there's some wording in the Standard that allows it?
你的程序对于 static
的情况也是错误的,正如在下面的问答中详细回答的那样:
但是,EWG 认为这是 constexpr 规范中的一个缺陷,并建议 CWG 考虑通过 P2280R3 解决它(在常量表达式中使用未知指针和引用),针对 C++23,并作为 C++11 到 C++20 的 DR(缺陷报告)。
jfbastien commented on Feb 3, 2021
EWG saw this paper in today's telecon.
P2280 Using unknown references in constant expressions
The use cases presented in P2280 are problems in C++’s specification of constexpr, and we would like to fix these problems, ideally in C++23.
This should be a Defect Report against C++20, C++17, C++14, and C++11.
然而,最终决定权在尚未研究该问题的 CWG。