Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will there be a concept for arithmetic types in C++ standard library?

I've been looking through concepts library on C++ reference and i couldn't find a concept for arithmetic types. I couldn't also find it in p0898. I think such concept would be very helpful. Insted of doing:

template <typename T>
T some_function(T arg) requires std::integral<T> || std::floating_point<T>
{ /* functions body */ }

I could just do:

template <std::arithmetic T>
T some_function(T arg)
{ /* functions body */ }

I could obviously define it myself and it wouldn't be hard (ex. template <typename T> concept arithmetic = std::integral<T> || std::floating_point<T>;), but in my opinion such basic concept should be defined in standard library. Is there any good reason why it's not there? Or is there any proposal to add it?

like image 643
Adam Bucior Avatar asked Sep 23 '19 17:09

Adam Bucior


People also ask

How many types of arithmetic are there in C++?

C++ uses operators to do arithmetic. It provides operators for five basic arithmetic calculations: addition, subtraction, multiplication, division, and taking the modulus.

What is an arithmetic type?

The arithmetic type specifiers are built up from the following keywords: void , char , int , float and double , together with the prefixes short , long , signed and unsigned . From these keywords you can build both integral and floating-point types.

What is the character constraints in C++?

Character constants are one or more members of the “source character set,” the character set in which a program is written, surrounded by single quotation marks ('). They are used to represent characters in the “execution character set,” the character set on the machine where the program executes.


2 Answers

Is there any good reason why it's not there? Or is there any proposal to add it?

There isn't any proposal to add it, but I would expect to see an NB comment that just proposes template <typename T> concept arithmetic = std::is_arithmetic_v<T>; (which doesn't guarantee that C++20 will have this concept, merely that at least it will be considered).

The standard library concepts were added by the Ranges proposal and were driven by needs in algorithms for certain concepts. integral comes up a lot, but I guess arithmetic never did and so it just never got added. If you look at, say, N4382 (from early 2015), you can see that Integral (and SignedIntegral and UnsignedIntegral) were there from the very beginning... whereas even FloatingPoint got added way later. (by P0631, in July 2019... and even the paper that added the floating point concept didn't make any mention of arithmetic)


Of course, then you get into the fun question of whether it should be based on strictly that type trait or should it be template <typename T> concept arithmetic = integral<T> || floating_point<T>; so that both the integral and floating_point concepts subsume arithmetic. Probably? Maybe?

like image 192
Barry Avatar answered Oct 02 '22 17:10

Barry


Disclaimer: I'm not a C++ expert, and not deeply familiar with C++ concepts. So the following answer might be a bit derailing, but I thought about this concept in a different context, and think that some of the points here may be relevant.

You did not exactly say what the concept should convey, beyond the example that it should cover integral and floating point types. But from a more theoretical, conceptual point of view, "arithmetics" could be applied much more broadly - even though the word arithmetics implies that it is about numbers.

Intuitively, one could expect the concept to convey the following:

The type in question supports the basic arithmetic operations, +, -, * and /, and the result type of these operations is the same as the type of the operands. From a quick websearch, this idea seems to be formalized roughly like that:

self operator+(self const& x, self const& y);
self operator−(self const& x, self const& y);
self operator∗(self const& x, self const& y);
self operator/(self const& x, self const& y);

However, there is more that is required for a proper arithmetic:

  • the there must be a closure of the elements under the given operation
  • there must be a neutral element of addition (0)
  • there must be a neutral element of multiplication (1)
  • there must be an additive inverse for each element (-x)
  • there must be a multiplicative inverse for each element (/x - except for the neutral element of addition...)

You see that a can of worms is opened here. These constraints are already hard or impossible to enforce for integral types, as there may be no additive inverse, particularly for unsigned types. For floating point types, the special cases grow out of hand quickly, due to +/-inf and most importantly: NaN. All this does not yet even consider the limited precision of floating point arithmetic.


Going one step further down the theoretical rabbit hole: The concept of arithmetics should probably be a special form (or combination) of general algebraic concepts. For example, it is perfectly fine to consider the unsigned integer types as a cyclic group, and to some extent, some structures involving integral or floating point types have properties that would be associated with a ring.


So a concept of arithmetics that goes beyond saying that it is "either float or int" would certainly be interesting, but has many caveats. Trying to formulate the concept cleanly, so that it may, for example, also be applied to complex numbers or similar structures, is difficult. And if one tried to define this, one would certainly also like to cover other algebraic structures like groups or rings (e.g. for matrices or polynomials) or even vector spaces...

Some people tried this, at least: A quick websearch revealed a Techcnical Report: Fundamental Algebraic Concepts in Concept-Enabled C++ that tackles some of these ideas, including arithmetics, and points out the difficulties that are associated with that. It's from 2006, though - there might be newer research, based on the concepts as they found their way into the standard.

like image 45
Marco13 Avatar answered Oct 02 '22 18:10

Marco13