Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Extending type traits from <type_traits>

21 views
Skip to first unread message

gereon...@gmail.com

unread,
Sep 12, 2014, 3:44:05 AM9/12/14
to
Hi everyone,

I'm (re-)designing type traits in a library and am kind of stuck.
Our library is about using several number types (along the lines of gmp) for polynomial algebra. For this, we decided to use type traits to distinguish between number types that are integral or are a field and alike.

Skimming through the STL, i discovered a bunch of type traits that look like they already kind of do what we want: is_integral, is_floating_point, is_fundamental.
So I decided to simply specialize them and add other ones like is_field.
So, for example, I'd do std::is_integral<mpz_class>::value = true.
However, this automatically makes std::is_fundamental<mpz_class>::value == true, which we do not want (for obvious reasons, I guess).
Now I could also specialize std::is_fundamental<mpz_class>, but this seems like an ugly workaround to me.

This basically boils down to the following:
Are the type traits from the STL meant to be extended / specialized for custom types? If so, is there a clear (preferably mathematical) definition of what is_integral or is_arithmetic means?
Or are these type traits only meant to be used for types from the STL and I should simply define my own, even if their functionality is basically the same?

Thanks in advance for any hints,
Gereon

Chris Vine

unread,
Sep 12, 2014, 7:03:54 AM9/12/14
to
This is an interesting question. On whether you can do it,
§17.6.4.2.1/1 of the C++11 standard states that:

"The behavior of a C++ program is undefined if it adds declarations
or definitions to namespace std or to a namespace within namespace std
unless otherwise specified. A program may add a template
specialization for any standard library template to namespace std
only if the declaration depends on a user-defined type and the
specialization meets the standard library requirements for the
original template and is not explicitly prohibited."

On 'is_integral' and 'is_arithmetic' in particular, §20.9.2/1 (which
includes those type trait structs) provides that "The behavior of a
program that adds specializations for any of the class templates
defined in this subclause is undefined unless otherwise specified."
This presupposes that there are some type traits amongst these which
are specified elsewhere in the standard as permitted to be specialized,
but I have to say I have not traced what they are, and I should be
interested if you find any. However, they do not appear to include the
ones in which you are interested.

Presumably the thinking behind this is that there should never normally
be a need to specialize 'is_integral', 'is_arithmetic' or any of the
other primary or composite type categories in §20.9.4.1 and §20.9.4.2
for user defined types, because these are features that by language
definition only a built-in type can possess. A type is integral if it
meets the definition in §3.9.1/7. It is arithmetic if it meets the
definition in §3.9.1/8.

I should have thought it would be less confusing to users of your
library if you provided your own type trait structs for extended
arithmetic types. And I would think it less confusing not to provide
your own type trait which suggests that an extended arithmetic type is
a fundamental type unless in fact it happens to be a typedef for a
fundamental type according to the language definition.

Chris

gereon...@gmail.com

unread,
Sep 12, 2014, 7:41:58 AM9/12/14
to
Thank you very much for your research on that.
It somewhat confirmed what I already feared.

While following your path through the standard, I noticed Note §20.9.4.1/3 stating "For any given type T, exactly one of the primary type categories has a value member that evaluates to true.". As both is_class and is_integral are part of these "Primary type categories", a class that represents integral can either be a class or an integral. This also hints, that is_integral, is_floating_point etc are only intended for native types.

So I'll define my own traits...

Thanks,
Gereon
0 new messages