【问题标题】:non-constexpr object usable in static_assert可在 static_assert 中使用的非 constexpr 对象
【发布时间】: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) 变量 arrarr2 具有其非静态但 constexpr 的语言机制/规则是什么?成员函数size() 被评估为常量表达式(尤其是 bool-constexpr)?

我现在花了一些时间搜索 SO 和 cppreference.com,但无法弄清楚为什么允许这样做。

当从旧版本的 GCC 升级时,我最近不得不更新类似的代码来执行 static_assert(std::tuple_size_v&lt;decltype(arr)&gt; == 8),所以我一开始认为它可能只是一些 GCC 扩展。但我现在已经让这种代码再次开始使用新版本的 GCC,我想了解这里发生了什么。

【问题讨论】:

标签: c++


【解决方案1】:

确实没有任何好的理由允许这样做:只是将(非 constexpr)局部变量的地址作为this 传递给成员函数是不在常量表达式的规则中考虑。甚至允许在被调用的函数中使用this,但你不能使用类的任何(非静态)成员变量,除非它们真的被初始化为常量。当然,这些尺寸函数不需要这样做,即使它们实际上不是静态

真正令人困惑的是,这个权限并没有扩展到references:使用它们被认为是读取有效指针值,并且必须单独是一个常量。有一些积极的提议允许在使用此类“未知对象”的成员变量的相同不可避免的限制下进行此类使用。

【讨论】:

  • 这也适用于(指针和引用)函数参数。如果你不使用它们,它们不需要是 constexpr:gcc.godbolt.org/z/rEx1cK7zf
猜你喜欢
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
  • 2016-09-16
相关资源
最近更新 更多