It is proper to make mt19937 static in a class - c++11

Let's say I have a class as below:
class Test {
public:
Test() : mt((std::random_device())()), dist1(0, 10), dist2(0, 100) {}
void func() {
if (dist1(mt) < 4) {
// do something
}
}
void func2() {
if (dist2(mt) > 25) {
// do something
}
}
private:
std::mt19937 mt;
std::uniform_int_distribution<int> dist1;
std::uniform_int_distribution<int> dist2;
};
As you see, there are two functions, they all need a random number to do something.
In this case, can I make the data member std::mt19937 mt as static and initialize it in cpp file?
class Test {
...
private:
static std::mt19937 mt;
...
};
// cpp file
std::mt19937 Test::mt((std::random_device())());
I just tried and it seemed to work. But I don't know if there is something wrong with it.
Test t1; t1.func(); t1.func2();
Test t2; t2.func(); t2.func2();
Can I say that static or non-static won't cause any difference for the piece of code?

Can I say that static or non-static won't cause any difference for the piece of code?
If you care about the specific sequence of numbers that each instance of Test will observe, yes. However you are seeding these with std::random_device, so I suspect you don't care about that.
If you have calls to these methods on multiple threads, the static version has a data race. I would use thread_local, not static, to share std::mt19937s.

Related

std::function and friend function

In this example, I have a pointer of function (std::function) as an attribute of my class. So I can associate any function of the form void myFunction(void) to my class.
#include <iostream>
#include <functional>
class Example{
private:
int variable=4;
public:
std::function<void(void)> myNonMemberFunction;
Example(void){
}
Example(std::function<void(void)> MyNonMemberFunction){
myNonMemberFunction=MyNonMemberFunction;
}
};
void PrintPlop(){
std::cout<<"plop"<<std::endl;
}
int main() {
Example example(PrintPlop);
example.myNonMemberFunction();
}
Now, I want to do the same but with a function which has accessed to the class attribute like a friend function or a class-member function. How can I do this?
So you want any function you pass to the constructor become a friend?
In the strict sense it is impossible, because the access level (friend or not) is a compile-time issue, and which value is passed to the constructor, generally speaking, is determined only in run-time.
So you either declare all the relevant functions as friends (why not just make them methods in this case?) or pass the private members to them as additional parameters. Like this:
class Example{
private:
int variable=4;
std::function<void(int)> myNonMemberFunction;
public:
Example(void){
}
Example(std::function<void(int)> MyNonMemberFunction){
myNonMemberFunction=MyNonMemberFunction;
}
void callMyNonMemberFunction() {
myNonMemberFunction(variable);
}
};
void PrintPlop(int v){
std::cout<<"plop"<< v << std::endl;
}
int main() {
Example example(PrintPlop);
example.callMyNonMemberFunction();
}

How to make a type alias depending on a compile-time constant within a class?

I want to write a class that makes use of numerical quadrature. The quadrature order defines the size of some containers that I will use. I would like to make a type alias for such containers and it has to depend on the quadrature order.
The following code shows my trials. It feels suboptimal in the sense that I have to repeat the order in the type alias definition:
#include <array>
class Quadrature
{
public:
static constexpr unsigned int getOrder()
{
return 3;
}
// This line doesn't compile!
//
// using WeightsContainer = std::array<double, getOrder()>;
//
// g++ says "error: 'static constexpr unsigned int Quadrature::getOrder()'
// called in a constant expression before its definition is complete"
// This line compiles, but repeats the order. :-(
using WeightsContainer = std::array<double, 3>;
private:
WeightsContainer container;
};
One solution that I have found is introducing a template parameter Order. But actually I wanted to determine the quadrature order and introducing the template parameter would make it variable.
Is there a possibility to make the order a compile-time constant and use it within my type alias definition?
Edit:
For completeness, I could of course use a preprocessor define. But that feels old-fashioned. :-)
Edit 2:
Okay, I have found another possibility. I could add a function outside the class scope like this:
constexpr unsigned int order()
{
return 3;
}
But that feels wrong, because this is a property of the class and therefore should be within class scope!
One thing you can do is to move the value into a member variable:
class Quadrature
{
private:
static constexpr unsigned int _order = 3;
public:
static constexpr unsigned int getOrder()
{
return _order;
}
using WeightsContainer = std::array<double, _order>;
// ...
};
If you need more complicated computations instead of just return 3, under C++17 you can use a lambda as #Quentin mentioned:
class Quadrature
{
public:
static constexpr auto getOrder = []()
{
return ...;
};
using WeightsContainer = std::array<double, getOrder()>;
// ...
};
Otherwise, you will need to pull the function outside of class scope for reasons mentioned here.

Is that possible to have a for loop in compile time with runtime or even compile time limit condition in c++11?

I would like to know if it is possible to have a for loop in compile time with runtime or even compile time limit condition in c++11?
I start with a silly try to find out what I need.
for (uint32_t i = 0; i < n; ++i)
{
templated_func<i>();
}
consider I have a class with a private member variable n, and I want to call a template function with a different number that iterates from 0 to n (for the case of runtime limit condition)
I've had studies on the "Template Metaprogramming" and "Constexpr If" (c++17) but I have not gotten any results, can anyone help me?
You can't have a for loop, but you can call N lots of templated_func
namespace detail {
template <template<uint32_t> class F, uint32_t... Is>
void static_for_impl(std::integer_sequence<uint32_t, Is...>)
{
F<Is>{}()...;
}
}
template <template<uint32_t> class F, uint32_t N>
void static_for()
{
detail::static_for_impl<F>(std::make_integer_sequence<uint32_t, N>{});
}
template <uint32_t I>
struct templated_caller
{
void operator()() { templated_func<I>(); }
}
int main()
{
static_for<templated_caller, 10>();
return 0;
}
Note that this is more general than what you asked for. You can simplify it to just
template <uint32_t... Is>
void call_templated_func(std::integer_sequence<uint32_t, Is...>)
{
templated_func<Is>()...;
}
int main()
{
call_templated_func(std::make_integer_sequence<uint32_t, N>{});
return 0;
}
but that's lengthy to repeat multiple times, and you can't pass a function template as a template parameter.
As you said you only had C++11 then you will not have std::make_index_sequence and will have to provide it. Also, the fold expression in Caleth's answer is not available until C++17.
Providing your own implementation of index_sequence and a fold expression in c++11 can be done in the following way,
#include <iostream>
template <size_t... Is>
struct index_sequence{};
namespace detail {
template <size_t I,size_t...Is>
struct make_index_sequence_impl : make_index_sequence_impl<I-1,I-1,Is...> {};
template <size_t...Is>
struct make_index_sequence_impl<0,Is...>
{
using type = index_sequence<Is...>;
};
}
template<size_t N>
using make_index_sequence = typename detail::make_index_sequence_impl<N>::type;
template<size_t I>
void templated_func()
{
std::cout << "templated_func" << I << std::endl;
}
template <size_t... Is>
void call_templated_func(index_sequence< Is...>)
{
using do_ = int[];
do_ {0,(templated_func<Is>(),0)...,0};
}
int main()
{
call_templated_func(make_index_sequence< 10>());
return 0;
}
This is essentially the same as the answer by #Caleth , but with the missing bits provided and will compile on c++11.
demo
demo on c++11 compiler
I would like to know if it is possible to have a for loop in compile time with runtime or even compile time limit condition in c++11
I don't know a reasonable way to have such loop with a runtime condition.
With a compile time condition... If you can use at least C++14, you can use a solution based on std::integer_sequence/std::make_integer_sequence (see Caleth answer) or maybe std::index_sequence/std::make_index_sequence (just a little more synthetic).
If you're limited with C++11, you can create a surrogate for std::index_sequence/std::make_index_sequence or you can create a recursive template struct with static function (unfortunately you can partially specialize a template function but you can partially specialize classes and structs).
I mean... something as follows
template <std::size_t I, std::size_t Top>
struct for_loop
{
static void func ()
{
templated_func<I>();
for_loop<I+1u, Top>::func();
}
};
template <std::size_t I>
struct for_loop<I, I>
{ static void func () { } };
that you can call
constexpr auto n = 10u;
for_loop<0, n>::func();
if you want to call templated_func() with values from zero to n-1u.
Unfortunately this solution is recursive so you can have troubles with compilers recursion limits. That is... works only if n isn't high.

How to use c++11 random library in a large application?

There are several good answers like this that offer a concise random-only application, but I'm having trouble expanding from that to a small part of a larger application.
Here's what I'm doing:
#include <random>
class RandomFP16
{
public:
static RandomFP16* GetInstance();
int GetRandom();
private:
static RandomFP16* singleton;
RandomFP16();
std::mt19937 mt;
std::uniform_int_distribution<int> dist;
};
RandomFP16* RandomFP16::GetInstance()
{
if(singleton == 0)
{
singleton = new RandomFP16();
}
return singleton;
}
RandomFP16::RandomFP16()
{
std::random_device rd;
//next two lines have errors
mt(rd());
dist(0x00000000, 0x00010000); //fixed-point 16.16
}
int RandomFP16::GetRandom()
{
return dist(mt);
}
So basically, I want one shared random generator that can be used anywhere anytime...at random. :-) Coming from embedded C and Windows C#, I see some strange syntax being used here, so I'm not sure how to structure things to get rid of these errors:
error: no match for call to '(std::mt19937 {aka std::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u>}) (std::random_device::result_type)'
mt(rd());
^
.
error: no match for call to '(std::uniform_int_distribution<int>) (int, int)'
dist(0x00000000, 0x00010000);
^
Okay, I got it. Posting anyway to save someone some work.
#include <random>
class RandomFP16
{
public:
static RandomFP16* GetInstance();
int GetRandom();
private:
static RandomFP16* singleton;
RandomFP16(std::random_device::result_type seed);
std::mt19937 mt;
std::uniform_int_distribution<int> dist;
};
RandomFP16* RandomFP16::singleton = 0;
RandomFP16* RandomFP16::GetInstance()
{
if(singleton == 0)
{
std::random_device rd;
singleton = new RandomFP16(rd());
}
return singleton;
}
RandomFP16::RandomFP16(std::random_device::result_type seed)
: mt(seed), dist(0x00000000, 0x00010000) //fixed-point 16.16
{
}
int RandomFP16::GetRandom()
{
return dist(mt);
}
Turns out the class definition was right; the problems were all in the implentation:
The static variable needs to be declared again outside the class definition. (no idea why)
Local variables (not pointers) with constructors must be initialized like this.
That added an argument to this constructor, which then had to be fed from GetInstance()

C++ class member callback and external library

I would like to solve this issue about class member function callback.
Imagine you have a function from an external library (which cannot be modified!) like this:
void fortranFunction(int n, void udf(double*) );
I would like to pass as the udf function above a function member of an existing class. Please look at the following code:
// External function (tipically from a fortran library)
void fortranFunction(int n, void udf(double*) )
{
// do something
}
// User Defined Function (UDF)
void myUDF(double* a)
{
// do something
}
// Class containing the User Defined Function (UDF)
class myClass
{
public:
void classUDF(double* a)
{
// do something...
};
};
int main()
{
int n=1;
// The UDF to be supplied is myUDF
fortranFunction(n, myUDF);
// The UDF is the classUDF member function of a myClass object
myClass myClassObj;
fortranFunction(n, myClassObj.classUDF); // ERROR!!
}
The last line of the code above results in a compilation error, because you cannot declare the classUDF member function as a static function.
Do you know if it is possible to solve this issue?
Probably Boost libraries could help me, but I do not know how (please consider that fortranFunction cannot be modified because is from an external library).
Thanks a lot!
Alberto
I don't understand, why can't you declare classUDF as static like this
class myClass {
public:
static void classUDF(double *a) {
...
}
};
and then pass it like
fortranFunction(n, myClass::classUDF);
You might try that solution (a little bit hacky, but I think, it should work for you):
void fortranFunction(int n, void udf(double*))
{
double d = static_cast<double>(n);
udf(&d);
}
class myClass {
public:
void classUDF(double* a) {
}
};
#ifdef _MSC_VER
#define THREADLOCALSTATIC __declspec(thread) static
#define THREADLOCAL
#else
#define THREADLOCALSTATIC static ___thread
#define THREADLOCAL ___thread
#endif
struct _trampolinebase {
THREADLOCALSTATIC _trampolinebase* current_trampoline;
};
THREADLOCAL _trampolinebase* _trampolinebase::current_trampoline = 0;
#undef THREADLOCAL
#undef THREADLOCALSTATIC
template<class CBRET, class CBARG1, class T>
struct _trampoline1 : _trampolinebase
{
typedef CBRET (T::*CALLBACKFN)(CBARG1);
_trampoline1(T& target, CALLBACKFN& callback)
: callback_(callback)
, target_(target)
{
assert(current_trampoline == 0);
current_trampoline = this;
}
static CBRET callback(CBARG1 a1) {
_trampoline1* this_ = static_cast<_trampoline1*>(current_trampoline);
current_trampoline = 0;
return this_->trampoline(a1);
}
private:
CBRET trampoline(CBARG1 a1) {
return (target_.*callback_)(a1);
}
CALLBACKFN& callback_;
T& target_;
};
template<class FRET, class FARG1, class CBRET, class CBARG1, class T, class F>
FRET call1_1(T& target, CBRET (T::*callback)(CBARG1), F& fortranfunction, FARG1 a)
{
typedef typename _trampoline1<CBRET, CBARG1, T> trampoline;
trampoline t(target, callback);
return fortranFunction(a, trampoline::callback);
}
int main()
{
int n=1;
myClass myClassObj;
call1_1<void,int,void,double*>(myClassObj, &myClass::classUDF, fortranFunction, 1);
}
With the 'threadlocal' stuff, this will work in multithreaded calls, too. You may omit that, if you don't use a multithreaded environment. It also works with recursive calls (e.g. if the callback calls another fortran function).
This solution works only for one single argument plus callback for the fortran function and one single argument in the callback function itself, but you should be able to extend it easily. This is also, why I called it 'call1_1' (fortran function with 1 argument, callbackfunction with 1 argument). FRET is the return type of the fortran function, FARG1 the type of the first argument (int in this case). CBRET and CBARG are the same for the callback function.
Before the fortran function is actually called, the target object is stored within a global (thread-local) variable. The fortran function calls a static callback function, which finally calls your member function.
I invented the trampolinebase to instantiate the static member, I could also have used a global variable for that (but for some reason, I don't like global variables too much) ;-)

Resources