1

I have a type TimeDuration. Right now it is literal type and I can use it as non-type template parameter. Such usage is very far away (compilation-wise) from type definition, so if anybody modifies TimeDuration such that it is no loner literal, it will be noticed much later.

So I put static_assert(std::is_literal_type_v<TimeDuration>); just after class definition. However, is_literal_type is deleted in c++20. What can I replace this with?

I know about Deprecated std::is_literal_type in C++17, but the answer basically says that my problem doesn't exist.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
MateuszL
  • 2,751
  • 25
  • 38
  • For reference, there was briefly `std::has_strong_structural_equality`, but when class-type NTTPs were rewritten and that term was removed the trait was deliberately [dropped without replacement](https://cplusplus.github.io/LWG/issue3354), partly because it wouldn’t be clear whether it was supposed to mean “supported in C++20” or “supported in current C++” in the future. – Davis Herring May 21 '20 at 18:35

2 Answers2

4

There is a very simple way to get a compile error on whether a type is appropriate for use in a non-type template parameter: use it in a NTTP. The compiler will complain if it's not appropriate.

You can easily write a small template somewhere and instantiate it explicitly with your type. Something like:

template<auto val> struct checker{};

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

is_literal_type wouldn't be appropriate anyway (which is why it's going away) because being a literal type isn't nearly as restrictive as C++20's user-defined NTTP rules. Yes, a user-defined NTTP must be a literal type, but it must also have a number of other qualities.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Great simple idea, thanks! In case sb else tries this, keep in mind this feature needs gcc-9+ or clang-11+ (or later, clang-10 doesn't work). – MateuszL May 21 '20 at 13:50
0

If you don't care about the unicity of the template signature (avoiding std::is_same with classes), you can simply pass a TimeDuration variable (or anything you want) by const reference:

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

But you cannot pass on-the-fly temporaries. You need to declare the referenced variable as static constexpr to ensure static storage duration.

Cevik
  • 313
  • 1
  • 4
  • 17