【问题标题】:How to static_assert that type is viable for template non-type parameter in c++20c++20中,如何静态断言该类型对于模板非类型参数是可行的
【发布时间】:2020-05-21 07:57:01
【问题描述】:

我有一个类型TimeDuration。现在它是literal type,我可以将它用作非类型模板参数。这种用法与类型定义相距甚远(编译方式),因此如果有人修改 TimeDuration 使其不再是单独的文字,那么稍后会注意到。

所以我把static_assert(std::is_literal_type_v<TimeDuration>); 放在类定义之后。但是,is_literal_type 在 c++20 中被删除了。我可以用什么代替它?

我知道Deprecated std::is_literal_type in C++17,但答案基本上说我的问题不存在。

【问题讨论】:

  • 作为参考,有简短的 std::has_strong_structural_equality,但是当类类型的 NTTP 被重写并且该术语被删除时,特征是故意的 dropped without replacement,部分原因是不清楚它是否是应该在未来表示“在 C++20 中支持”或“在当前 C++ 中支持”。

标签: c++ templates c++20 constexpr


【解决方案1】:

有一个非常简单的方法可以得到关于一个类型是否适合在非类型模板参数中使用的编译错误:在 NTTP 中使用它。如果不合适,编译器会抱怨。

您可以轻松地在某处编写一个小模板并使用您的类型显式实例化它。比如:

template<auto val> struct checker{};

template struct checker<MyType(/*insert params for constexpr function here*/)>;

is_literal_type 无论如何都不合适(这就是它消失的原因),因为作为文字类型并不像 C++20 的用户定义 NTTP 规则那样具有限制性。是的,用户定义的 NTTP 必须是文字类型,但它还必须具有许多其他特性。

【讨论】:

  • 好简单的主意,谢谢!如果 sb else 尝试这样做,请记住此功能需要 gcc-9+ 或 clang-11+(或更高版本,clang-10 不起作用)。
【解决方案2】:

如果您不关心模板签名的唯一性(避免 std::is_same 与类),您可以简单地通过 const 引用传递一个 TimeDuration 变量(或任何您想要的):

template <const auto& TimeDurationRef>
requires std::is_same_v<std::decay_t<decltype(TimeDurationRef)>, TimeDuration>
void foo();// or struct Foo {};

但是您不能通过即时临时人员。您需要将引用的变量声明为 static constexpr 以确保静态存储持续时间。

【讨论】:

    猜你喜欢
    • 2020-05-02
    • 2021-02-07
    • 2023-02-05
    • 2023-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 2013-06-27
    相关资源
    最近更新 更多