Why can we not present uint8_t as a template parameter for number distributions?

942 views
Skip to first unread message

Tomalak Geret'kal

unread,
Dec 6, 2014, 6:18:04 PM12/6/14
to std-dis...@isocpp.org
Take the following C++11 (and C++14 wording) from the requirements for random number generation class templates:

[C++11: 26.5.1.1/1e]: that has a template type parameter named IntType is undefined unless the corresponding template argument is cv-unqualified and is one of short, int, long, long long, unsigned short, unsigned int, unsigned long, or unsigned long long.

Due to e.g.:

[C++11: 26.5.8.2.1/1]: [..]
template<class IntType = int>
class uniform_int_distribution

[..]

we can't legally do things like this:

#include <iostream>
#include <random>
#include <cstdint>

int main()
{
std::default_random_engine generator;
std::uniform_int_distribution<std::uint8_t> distribution(0, 100);
std::cout << +distribution(generator);
}

Here are some real-world results from my tests:

g++ (GCC) 5.0.0 20141119 (experimental) - compiles but outputs 0 in every run
g++ (GCC) 4.9.0 - compiles but outputs 0 in every run (demo)
g++ (GCC) 4.8.1 - compiles but outputs 0 in every run (demo)
MSVS 2012 - builds and runs and has intuitive output
MSVS 2013 - builds and runs and has intuitive output
MSVS 2015 - compilation error: "invalid template argument for uniform_int_distribution"

Due to the UB, all of these results are perfectly compliant. But can't we deem this to be a flaw in the standard itself? It seems that, in this day and age of standardised fixed-width types, allowing only the standard integer types ([basic.fundamental]/2) for IntType is a fundamental limitation, and an unnecessary one at that.

Cheers,
Tom

Tomalak Geret'kal

unread,
Dec 6, 2014, 6:22:33 PM12/6/14
to std-dis...@isocpp.org
Actually I've just realised it's even more simple than the above: unsigned char is in fact a standard unsigned integer type, despite not being listed in the IntType definition. This is a clear inconsistency.

David Krauss

unread,
Dec 7, 2014, 1:54:06 AM12/7/14
to std-dis...@isocpp.org
On 2014–12–07, at 7:22 AM, Tomalak Geret'kal <tom...@gmail.com> wrote:

Actually I've just realised it's even more simple than the above: unsigned char is in fact a standard unsigned integer type, despite not being listed in the IntType definition. This is a clear inconsistency.

The exclusion of character types as template arguments may be on purpose, for the sake of simplifying implementations.

Any concept requirements that result_type be an unsigned integer type (or something else) apply to all classes conforming to such concepts, not only the standard ones. That accounts for the inconsistency. However, in your example, you’re instantiating a distribution, not a generator, and distributions are allowed to have character result types. Only the template argument restriction applies.

Have you measured an improvement or advantage to using unsigned char instead of unsigned short?

It may be significant, though, that most users use fixed-size typedefs, and uint16_t could be an alias to unsigned char. A better specification would require specific numeric ranges for specific classes.

Tomalak Geret'kal

unread,
Jan 22, 2015, 5:08:39 AM1/22/15
to std-dis...@isocpp.org
Daniel Krugler has pointed out that this is already LWG issue 2326 (http://cplusplus.github.io/LWG/lwg-active.html#2326); not sure how I missed that when submitting it myself. :(
Reply all
Reply to author
Forward
0 new messages