1

The following program (that uses a standard random number engine) gives a "template argument deduction/substitution failed" compilation error:

http://coliru.stacked-crooked.com/a/e3c3ac933ed7b958

/// LCE1.cpp
///
/// Tests the linear congruential engine.
///
/// Dir: SW > Applications > Samples > C++Samples > Introductory > StdLib > Numerics > RandomNumbers > Engines > LCE > LCE1
///

#include <random>           /// linear_congruential_engine
#include <iostream>

using namespace std;


/// Generate random numbers using the specified engine.
template<typename Eng>
void gener();


int main()
{
   gener<typename decltype(linear_congruential_engine)>();
}


/// Generate random numbers using the specified engine.
template<typename Eng>
void gener()
{
    /// Create an engine of the specified type.
    Eng e;

    /// Generate 500 random numbers.
    for (int i = 0; i < 500; ++i)
        e();

    cout << "OK" << endl;
}

The compilation error is:

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:21:4: error: parse error in template argument list

    gener<typename decltype(linear_congruential_engine)>();
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

main.cpp:21:57: error: no matching function for call to 'gener<<expression error> >()'

    gener<typename decltype(linear_congruential_engine)>();
                                                         ^
main.cpp:16:6: note: candidate: template<class Eng> void gener()
 void gener();
      ^~~~~

main.cpp:16:6: note:   template argument deduction/substitution failed:
main.cpp:21:57: error: template argument 1 is invalid
    gener<typename decltype(linear_congruential_engine)>();
                                                     ^

Why does this happen? What's the solution?

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
SSteven
  • 733
  • 5
  • 17
  • `typename decltype(linear_congruential_engine)` -> `linear_congruential_engine` – HolyBlackCat Feb 23 '18 at 08:52
  • Also: ["Why is `using namespace std` considered bad practice? "](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – HolyBlackCat Feb 23 '18 at 08:52
  • One problem is that [`std::linear_congruential_engine`](http://en.cppreference.com/w/cpp/numeric/random/linear_congruential_engine) is a *template*, you can't get a type from it without providing suitable template arguments to it. And if you do, then you have a type, so don't need to use `decltype`. – Some programmer dude Feb 23 '18 at 08:53

1 Answers1

2

Firstly, std::linear_congruential_engine is a class template, you need to specify template arguments for it, e.g. linear_congruential_engine<std::uint_fast32_t, 16807, 0, 2147483647>.

And linear_congruential_engine<std::uint_fast32_t, 16807, 0, 2147483647> refers to a type, typename and decltype are needless.

As an example, you can change

gener<typename decltype(linear_congruential_engine)>();

to

gener<linear_congruential_engine<std::uint_fast32_t, 16807, 0, 2147483647>>();

Live Sample

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • So that's why examples on sites like cplusplus.com use predefined instantiations of linear_congruential_engine, such as minstd_rand. – SSteven Feb 23 '18 at 10:52
  • @SSteven Yes, you should use that too if it does match your requirement. Same as `std::string`, we usually won't use it as `std::basic_string`. – songyuanyao Feb 23 '18 at 10:56