【发布时间】:2021-07-01 02:42:53
【问题描述】:
我先举个例子
#include <array>
// Just in case std::array has superpowers...
template <typename T, unsigned n>
struct dummy {
constexpr unsigned size() const noexcept {
return n;
}
unsigned badsize() const noexcept {
return n;
}
};
void fun()
{
std::array<int, 8> arr{};
static_assert(arr.size() == 8); // OK
dummy<int, 8> arr2{};
static_assert(arr2.size() == 8); // OK
static_assert(arr2.badsize() == 8); // Compiler Error
}
问题是:
允许 non-const(expr) 变量 arr 和 arr2 具有其非静态但 constexpr 的语言机制/规则是什么?成员函数size() 被评估为常量表达式(尤其是 bool-constexpr)?
我现在花了一些时间搜索 SO 和 cppreference.com,但无法弄清楚为什么允许这样做。
当从旧版本的 GCC 升级时,我最近不得不更新类似的代码来执行 static_assert(std::tuple_size_v<decltype(arr)> == 8),所以我一开始认为它可能只是一些 GCC 扩展。但我现在已经让这种代码再次开始使用新版本的 GCC,我想了解这里发生了什么。
【问题讨论】:
-
有趣。如果
size访问一个数据成员,那么arr必须是constexpr。 godbolt.org/z/jvv9PTbf4 -
en.cppreference.com/w/cpp/language/constexpr 这里他们在 constexpr 函数的约束中提到了“核心常量表达式”。 (见下一条评论)
-
en.cppreference.com/w/cpp/language/constant_expression 这里他们定义了“核心常量表达式”,看列表中的第一个术语,虽然我看不懂,但它对这个指针有特殊处理。
标签: c++