https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87982
Jan van Dijk <j.v.dijk at tue dot nl> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |j.v.dijk at tue dot nl --- Comment #3 from Jan van Dijk <j.v.dijk at tue dot nl> --- Isn't the real problem that the standard does not specify any requirements about the type of the count argument (or a precondition on its value)? Should that be a built-in integral type? Then the issue is solved by doing a static_assert<is_integral_v<_Size>> to the implementation. One could also argue that the counter merely be convertible to a std::size_t, and the question (to WG21) is why then the count type is a template argument in the first place. (One could also argue that it should be a std::ptrdiff_t, since the algorithm really operates on a range [ptr,ptr+count] --- that would also allow an assert(count>=0) in the implementation.) If the intention is really that also user-defined types are supported, the requirements on such types should be spelled out (by WG21). As an example, the code below uses a custom counter object that can can be converted to (=> and compared with) an integer value. Reasonable enough. However, it does not compile because of what really seems to be an undocumented implementation detail in stl_algo.h: the usage of decltype(__n + 0) to compute a counter type for internal usage. Is the code below valid or not? It is remarkable how much Sunday morning can be spent on such an innocuous issue :-) cat 87892_2.cpp #include <algorithm> struct counter { counter(unsigned n); operator unsigned() const; counter& operator--(); private: template <class T> counter operator+(T v) const; }; void foo() { int a[2]; std::generate_n(a, counter(2), []{ return 0;}); } g++ -c 87892_2.cpp In file included from /home/jan/local/gcc-head/include/c++/9.0.1/algorithm:62, from 87892_2.cpp:1: /home/jan/local/gcc-head/include/c++/9.0.1/bits/stl_algo.h: In instantiation of ‘_OIter std::generate_n(_OIter, _Size, _Generator) [with _OIter = int*; _Size = counter; _Generator = foo()::<lambda()>]’: 87892_2.cpp:15:48: required from here /home/jan/local/gcc-head/include/c++/9.0.1/bits/stl_algo.h:4448:27: error: ‘counter counter::operator+(T) const [with T = int]’ is private within this context 4448 | for (__decltype(__n + 0) __niter = __n; | ~~~~^~~ 87892_2.cpp:9:29: note: declared private here 9 | template <class T> counter operator+(T v) const; |