The following code attempts to use ns::generateInt() as the Generator argument to std::generate_n():
// main.cpp
#include <vector>
#include <algorithm>
#include <ctime>
static int _tmp = ( srand( time( NULL ) ), 0 );
namespace ns
{
int generateInt( int offset = 0 )
{
return offset + rand() % 128;
}
}
int main( int argc, char* argv[] )
{
std::vector<int> v;
int tmp = ns::generateInt(); // Fine to call ns::generateInt() w/ 0 args
std::generate_n( std::back_inserter( v ),
5,
ns::generateInt ); // Not accepted as 0-arg Generator
return 0;
}
This code generates the following compile error:
$ g++ --version && g++ ./main.cpp
g++ (GCC) 9.2.1 20190827 (Red Hat 9.2.1-1)
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
In file included from /usr/include/c++/9/algorithm:62,
from ./main.cpp:4:
/usr/include/c++/9/bits/stl_algo.h: In instantiation of ‘_OIter std::generate_n(_OIter, _Size, _Generator) [with _OIter = std::back_insert_iterator<std::vector<int> >; _Size = int; _Generator = int (*)(int)]’:
./main.cpp:26:36: required from here
/usr/include/c++/9/bits/stl_algo.h:4493:18: error: too few arguments to function
4493 | *__first = __gen();
| ~~~~~^~
I know that the std::generate_n() signature takes a Generator function/functor that takes 0 arguments, but the argument to ns::generateInt() has a default value; and as shown above, in non-templated code, I can invoke ns::generateInt() with no arguments.
If the only change made to the above code is this...
int generateInt( /*int offset = 0*/ )
{
return /*offset +*/ rand() % 128;
}
...then it compiles just fine:
$ g++ ./main.cpp
$
What's going on from the compiler's perspective here? My default-argumented generator function is invokable with 0 arguments, so why is it not usable as the Generator argument to std::generate_n()?