当显式默认析构函数时(例如:)struct s { ~s() = default; };,似乎该类型仍然可以在constexpr上下文中使用。但是,当显式删除析构函数(例如:)时struct s { ~s() = delete; };,Clang 不再认为该类型对于constexpr上下文是可行的。那么,正如标题所暗示的那样,具有显式删除的析构函数的类型仍然可以在上下文中使用吗constexpr?
struct a { ~a() = default; };           // all ok
struct b { ~b(){} };                    // all fail
struct c { ~c() = delete; };            // fails on clang
struct d { constexpr ~d() = default; }; // all ok
struct e { constexpr ~e(){} };          // all ok
struct f { constexpr ~f() = delete; };  // all ok
static_assert(noexcept([]<c>{}));
Clang 16.0.0 和 Clang trunk 产生的错误:
<source>:9:28: error: non-type template parameter has non-literal type 'c'
static_assert(noexcept([]<c>{}));
                           ^
<source>:3:12: note: 'c' is not literal because its destructor is not constexpr
struct c { ~c() = delete; };            // fails on clang
           ^
Art*_*yer 15
要使一个类成为文字类型,您所需要的只是一个constexpr析构函数。= deleted 功能已经被允许存在constexpr 很长时间了。
但是,如果您不标记它constexpr,那么它除了constexpr具有额外规则([class.dtor]p9)的默认析构函数之外:
如果默认析构函数满足 constexpr 析构函数 ([dcl.constexpr]) 的要求,则它是 constexpr 析构函数。
没有成员的类会这样做,~a() = default;constexpr 也是如此。
~c() = delete;不是 constexpr 因为没有理由这样做。
constexpr ~f() = delete;是 constexpr 因为它被标记为constexpr.
Clang 在这里是正确的:如果未指定,则不会,因此不能用作文字类型~s() = delete;。constexpr看来std::is_literal_v<c>gcc 错误地传递了。
| 归档时间: | 
 | 
| 查看次数: | 1154 次 | 
| 最近记录: |