2

Suppose I create my own floating point type MyFloatingPoint (e.g. to provide increased precision relative to the built-in types). Is it permissible to specialize the constants in the C++20 <numbers> header for this type, or is this undefined behavior?

3 Answers3

3

Yes, but only if the specialization depends on a program-defined type (rather than only built-in / standard library types).

See [math.constants]/2 in the post-C++20 draft of the C++ standard.

Note that without such a specific permission in the standard, it is generally not allowed to specialize a standard library variable template. See [namespace.std]/3.

user17732522
  • 53,019
  • 2
  • 56
  • 105
  • The topic of specializing standard library templates is slightly more complex I'd say, see e.g.: [this](https://stackoverflow.com/a/16519653/4885321). – alagner Dec 31 '21 at 14:10
  • @alagner Yes, in general for standard library templates it is more complex. But specifically for standard library _variable_ templates the linked paragraph generally forbids specialization without specific permission. Many of the answers/comments in the question you linked were written before variable templates existed, so they might not be taking that into account. – user17732522 Dec 31 '21 at 14:16
2

According to C++20 draft it seems fine:

26.9.2 (...) 2. Pursuant to 16.5.4.2.1, a program may partially or explicitly specialize a mathematical constant variable template provided that the specialization depends on a program-defined type

alagner
  • 3,448
  • 1
  • 13
  • 25
-1

No it isn't undefined behavior (be careful when to use that term). I don't see any big issues with that (specialy not after reading the other comments).

#include <numbers>

struct my_floatingpoint_t
{
    double value;
};

namespace std
{
    namespace numbers
    {
        template<>
        constexpr my_floatingpoint_t pi_v<my_floatingpoint_t>{3.14};
    }
}


int main()
{
    auto pi = std::numbers::pi_v<double>;
    auto my_pi = std::numbers::pi_v<my_floatingpoint_t>;
    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
  • I suppose one should be careful here, since it is by default forbidden to specialize standard library variable templates. See https://timsong-cpp.github.io/cppwp/n4868/namespace.std#3. The `` ones just give specific permission. – user17732522 Dec 31 '21 at 14:08
  • I agree, it is always advisable to put your own stuff in other namespaces then std – Pepijn Kramer Dec 31 '21 at 14:20
  • I think identifiers ending in _t are not allowed – Sebastian Dec 31 '21 at 15:56
  • @Sebastion I double checked, it is not forbidden it is a POSIX naming convention. So you can run into naming conflicts if you use POSIX. So like any C++ program its best to define your own types in a namespace (I always do that in bigger projects, but I tend to skip it for examples). – Pepijn Kramer Dec 31 '21 at 16:04
  • So only reserved in Posix and not in the C++ standard itself – Sebastian Dec 31 '21 at 17:51
  • 1
    Yup, just found this topic. It discusses it in detail : https://stackoverflow.com/questions/231760/what-does-a-type-followed-by-t-underscore-t-represent/12727104#12727104 (Seems to be more related to "C" then "C++" unless I missed something) – Pepijn Kramer Dec 31 '21 at 17:54