Efficient boost distribution usage - c++

(Rephrased the question)
I'm creating a wrapper class for boost normal distribution, and want to make it as efficient as possible.
If I use:
double x = 0.0;
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor(rng, nd);
for (int i=0; i<20; i++) {
double x = var_nor();
}
The loop works fine. My concern is that I don't want to be declaring anything unnecessarily as the method gets called many times. I tried splitting up the code and put this line in the constructor:
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor(rng, nd);
and have a sample method that does this:
double x = var_nor();
return x;
But in this case, I get an error saying var_nor() (ie. with no arguments) is not found.
Can anyone tell me what's going on with these boost declarations ie. what does the
boost:variate_generate etc.
line actually do in with var_nor?
With my limited C++ knowledge, it looks as if var_nor is being defined with two different signatures.
Thanks guys
Pete

In your code, var_nor is a variable, not a function, so it doesn't have a signature. It represents a variate_generator object that can behave like a function because it supports operator().
In your code, you declare and initialize var_nor at the same time. The rng and nd arguments are passed to the constructor of the variate_generator object.
When you moved the declaration into your class's constructor, you were declaring var_nor as a local variable in the constructor, so it's no wonder it wasn't available elsewhere. For something to be available throughout an entire class, it needs to be a member variable. Declare it private in the class:
class NormalDistribution
{
boost::random::mt19937 _rng;
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor;
public:
NormalDistribution();
};
Then initialize it in the constructor:
NormalDistribution::NormalDistribution():
_rng(), var_nor(_rng, boost::normal_distribution<>(0.0, 1.0))
{ }
The _rng member needs to be declared first so that it will be initialized first. The nd parameter can be omitted and replaced with a temporary normal_distribution object passed directly to the var_nor constructor as shown above.
With those changes, you should be able to use the same normal_distribution object over multiple calls to your sample function, or whatever other uses you have for your NormalDistribution class.
In the code you've since deleted from your question, you were confusing variable declarations with function declarations. You declared nd as a function receiving two parameters and returning a normal_distribution. Likewise with var_nor. It was a function when you really wanted an object. You were confused because it happens to be an object that acts like a function, but it's still just an object.

OK, working final version using Rob Kennedy's answer, for others that might be interested:
// normaldistribution.h
#ifndef NORMALDISTRIBUTION_H
#define NORMALDISTRIBUTION_H
#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>
class NormalDistribution
{
public:
NormalDistribution();
double sample(void);
private:
// Use the boost random number generator
boost::mt19937 rng;
// Make a variate_generator OBJECT.
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor;
};
#endif // NORMALDISTRIBUTION_H
// normaldistribution.cpp
NormalDistribution::NormalDistribution():
rng(), var_nor(rng, boost::normal_distribution<>(0.0, 1.0))
{
std::cout << "Called normal distribution constructor, passing up var_nor" << std::endl;
}
double NormalDistribution::sample(void) {
double x = var_nor();
return x;
}
// main.cpp
#include "normaldistribution.h"
int main(int argc, char *argv[])
{
NormalDistribution *nd = new NormalDistribution();
for (int i=0; i < 10; ++i)
{
double d = nd->sample();
std::cout << d << std::endl;
}
return 0;
}

Related

Get call identifier or address of a function

Suppose that I have this code:
class MyClass
{
public:
void SomeFunction()
{
// Find somehow if this is first, second, or third call of a function in a main loop
// If the function is called first time create new variables that will be used just for this function call
}
};
MyClass myClassObject;
int main()
{
myClassObject.SomeFunction(); // First call
myClassObject.SomeFunction(); // Second call
myClassObject.SomeFunction(); // Third call
}
How can I know inside function what number of call is it?
Note that I will probably have 100 function calls placed in code. Also this should work in Visual Studio on Windows and Clang on Mac.
I had one workaround:
void SomeFunction(const char* indetifier = "address")
{
CheckAddress(indetifier); // This will check if address is stored. If it is not, create variables, if it is, if addresses matches use variables that are tied to that address.
}
I tried not to assign a new string to an "indetifier" and to let it to use default string ("address"). This of course didn't worked well as compiler will optimize "indetifier", so I was thinking that maybe a solution would be to disable optimizations for that variable, but I didn't because there should be some more elegant solution.
Also one thing came on my mind, maybe I could force inline a function and then get it's address, but this also seams like bad workaround.
I could also create new classes for every call but I would like to avoid this as there will be a lot of function calls and I don't want to think 100 different names.
If there is a way to create class object only at first call this would be awesome.
I hope that you understand what I want, sorry if something is not that clear as I am beginner coder.. :D
EDIT:
I can't use static for variables in a class because software that I am developing is a plugin that could have multiple instances loaded inside host and this will probably mess up the variables. I have tested static variables and if I create for example "static int value" anywhere and write something in it in one instance of a plugin this "value" will be updated for all instances of a plugin and this is not something that I want.
void SomeFunction()
{
// Find somehow if this is first, second, or third call of a function in a main loop
// If the function is called first time create new variables that will be used just for this function call
}
If the first call is to be tracked per object, then you need a member variable that keeps track of how many times SomeFuntion has been called for that object.
If the first call is to be tracked independent of objects, then you can use a static function variable that keeps track of how many times SomeFuntion has been called for that object.
I can't use static for variables in a class because software that I am developing is a plugin that could have multiple instances loaded inside host and this will probably mess up the variables. I have tested static variables and if I create for example "static int value" anywhere and write something in it in one instance of a plugin this "value" will be updated for all instances of a plugin and this is not something that I want.
So make a non-static counter?
class MyClass {
int count;
public:
MyClass () : count(0) { }
void SomeFunction () {
++ count;
// do stuff with 'count'
}
};
MyClass myClassObject;
int main () {
myClassObject.SomeFunction(); // First call
myClassObject.SomeFunction(); // Second call
myClassObject.SomeFunction(); // Third call
}
Or just pass it as a parameter...
class MyClass {
public:
void SomeFunction (int count) {
// do stuff with 'count'
}
};
MyClass myClassObject;
int main () {
myClassObject.SomeFunction(1); // First call
myClassObject.SomeFunction(2); // Second call
myClassObject.SomeFunction(3); // Third call
}
But I'm really wondering what you're actually trying to do, and I highly suggest sitting back and rethinking this whole thing, because there are a number of red flags / confusing points here...
If you're only interested in checking whether it's the first call, you can add a bool SomeFunction_first_call; to the MyClass, to act as a flag. The constructor sets the bool to true. MyClass::SomeFunction() uses the conditional check if (SomeFunction_first_call) /* ... */ to determine whether it's the first call, as follows:
class MyClass
{
bool SomeFunction_first_call;
public:
MyClass() : SomeFunction_first_call(true) {}
void SomeFunction()
{
if (SomeFunction_first_call)
{
// This code only executes on first call.
do_something();
// Successfully handled first call, set flag to false.
SomeFunction_first_call = false;
}
// This code always executes.
do_something();
}
};
Similarly, if you're only concerned about the first HOWEVER_MANY_CALLS calls, where HOWEVER_MANY_CALLS is a number, you can use something like this:
#include <cstdint>
class MyClass
{
uint8_t SomeFunction_calls;
public:
MyClass() : SomeFunction_calls(0) {}
void SomeFunction()
{
// This segment will be executed until (SomeFunction_calls == HOWEVER_MANY_CALLS).
// After this, the segment will be skipped, and the counter will no longer increment.
if (SomeFunction_calls < HOWEVER_MANY_CALLS)
{
// This code only executes on first HOWEVER_MANY_CALLS calls.
do_something();
// Increment counter.
++SomeFunction_calls;
}
// This code always executes.
do_something();
}
};
Make sure to use the appropriately signed variable for the number of calls that need special handling (i.e. uint8_t for 0..255, uint16_t for 256..65,535, etc.). If different instances of MyClass will need to keep track of a different number of calls, then use a non-type template parameter to indicate this, and optionally, a defaulted typename to indicate what type the counter should be.
#include <cstdint>
template<uint64_t N, typename T = uint64_t>
class MyClass {
T SomeFunction_calls;
...
void SomeFunction()
{
if (SomeFunction_calls < N) {
...
}
...
}
};
In this case, a MyClass<4> will have special treatment for the first 4 calls to SomeFunction(), a MyClass<4444444444444444444> will have special treatment for the first 4,444,444,444,444,444,444 calls, and so on. The counter will default to uint64_t, as that should be large enough to hold the value; when only a smaller number of calls need special treatment, you can specify a smaller type, such as MyClass<4, uint8_t> or MyClass<444444444, uint32_t>.
In C++ you can use the static keyword in a local variable context to create the object only once at the first call:
#include <iostream>
struct MyObject {
MyObject() {
std::cout << "Creating instance " << this << "\n";
};
};
void foo() {
static MyObject my_instance;
std::cout << "... inside function foo ...\n";
}
int main(int argc, const char *argv[]) {
std::cout << "About to call foo...\n";
foo();
std::cout << "... second call ...\n";
foo();
std::cout << "... third call ...\n";
foo();
return 0;
}
With the above code you will notice that only on object MyObject will be created, on the first call to foo.
Note that if your function is a template then for each instantiation of the template you will get another distinct static variable. For example with:
template<int N>
void foo() {
static MyObject my_instance;
std::cout << "... inside function foo ...\n";
}
the all the calls to foo<1>() will use the same variable but calling instead foo<2>() will access another copy of the function (another instantiation of the function template), that will have its own distinct static variable created on the first call to foo<2>(). All static variables that have been initialized will be destroyed after the end of main when the program terminates.

Running C++ code outside of functions scope

(I know) In c++ I can declare variable out of scope and I can't run any code/statement, except for initializing global/static variables.
IDEA
Is it a good idea to use below tricky code in order to (for example) do some std::map manipulation ?
Here I use void *fakeVar and initialize it through Fake::initializer() and do whatever I want in it !
std::map<std::string, int> myMap;
class Fake
{
public:
static void* initializer()
{
myMap["test"]=222;
// Do whatever with your global Variables
return NULL;
}
};
// myMap["Error"] = 111; => Error
// Fake::initializer(); => Error
void *fakeVar = Fake::initializer(); //=> OK
void main()
{
std::cout<<"Map size: " << myMap.size() << std::endl; // Show myMap has initialized correctly :)
}
One way of solving it is to have a class with a constructor that does things, then declare a dummy variable of that class. Like
struct Initializer
{
Initializer()
{
// Do pre-main initialization here
}
};
Initializer initializer;
You can of course have multiple such classes doing miscellaneous initialization. The order in each translation unit is specified to be top-down, but the order between translation units is not specified.
You don't need a fake class... you can initialize using a lambda
auto myMap = []{
std::map<int, string> m;
m["test"] = 222;
return m;
}();
Or, if it's just plain data, initialize the map:
std::map<std::string, int> myMap { { "test", 222 } };
Is it a good idea to use below tricky code in order to (for example)
do some std::map manipulation ?
No.
Any solution entailing mutable non-local variables is a terrible idea.
Is it a good idea...?
Not really. What if someone decides that in their "tricky initialisation" they want to use your map, but on some system or other, or for not obvious reason after a particular relink, your map ends up being initialised after their attempted use? If you instead have them call a static function that returns a reference to the map, then it can initialise it on first call. Make the map a static local variable inside that function and you stop any accidental use without this protection.
§ 8.5.2 states
Except for objects declared with the constexpr specifier, for which
see 7.1.5, an initializer in the definition of a variable can consist
of arbitrary expressions involving literals and previously declared
variables and functions, regardless of the variable’s storage duration
therefore what you're doing is perfectly allowed by the C++ standard. That said, if you need to perform "initialization operations" it might be better to just use a class constructor (e.g. a wrapper).
What you've done is perfectly legal C++. So, if it works for you and is maintainable and understandable by anybody else who works with the code, it's fine. Joachim Pileborg's sample is clearer to me though.
One problem with initializing global variables like this can occur if they use each other during initialization. In that case it can be tricky to ensure that variables are initialized in the correct order. For that reason, I prefer to create InitializeX, InitializeY, etc functions, and explicitly call them in the correct order from the Main function.
Wrong ordering can also cause problems during program exit where globals still try to use each other when some of them may have been destroyed. Again, some explicit destruction calls in the correct order before Main returns can make it clearer.
So, go for it if it works for you, but be aware of the pitfalls. The same advice applies to pretty much every feature in C++!
You said in your question that you yourself think the code is 'tricky'. There is no need to overcomplicate things for the sake of it. So, if you have an alternative that appears less 'tricky' to you... that might be better.
When I hear "tricky code", I immediately think of code smells and maintenance nightmares. To answer your question, no, it isn't a good idea. While it is valid C++ code, it is bad practice. There are other, much more explicit and meaningful alternatives to this problem. To elaborate, the fact that your initializer() method returns void* NULL is meaningless as far as the intention of your program goes (i.e. each line of your code should have meaningful purpose), and you now have yet another unnecessary global variable fakeVar, which needlessly points to NULL.
Let's consider some less "tricky" alternatives:
If it's extremely important that you only ever have one global instance of myMap, perhaps using the Singleton Pattern would be more fitting, and you would be able to lazily initialize the contents of myMap when they are needed. Keep in mind that the Singleton Pattern has issues of its own.
Have a static method create and return the map or use a global namespace. For example, something along the lines of this:
// global.h
namespace Global
{
extern std::map<std::string, int> myMap;
};
// global.cpp
namespace Global
{
std::map<std::string, int> initMap()
{
std::map<std::string, int> map;
map["test"] = 222;
return map;
}
std::map<std::string, int> myMap = initMap();
};
// main.cpp
#include "global.h"
int main()
{
std::cout << Global::myMap.size() << std::endl;
return 0;
}
If this is a map with specialized functionality, create your own class (best option)! While this isn't a complete example, you get the idea:
class MyMap
{
private:
std::map<std::string, int> map;
public:
MyMap()
{
map["test"] = 222;
}
void put(std::string key, int value)
{
map[key] = value;
}
unsigned int size() const
{
return map.size();
}
// Overload operator[] and create any other methods you need
// ...
};
MyMap myMap;
int main()
{
std::cout << myMap.size() << std::endl;
return 0;
}
In C++, you cannot have statements outside any function. However, you have global objects declared, and constructor (initializer) call for these global objects are automatic before main starts. In your example, fakeVar is a global pointer that gets initialized through a function of class static scope, this is absolutely fine.
Even a global object would do provide that global object constructor does the desired initializaton.
For example,
class Fake
{
public:
Fake() {
myMap["test"]=222;
// Do whatever with your global Variables
}
};
Fake fake;
This is a case where unity builds (single translation unit builds) can be very powerful. The __COUNTER__ macro is a de facto standard among C and C++ compilers, and with it you can write arbitrary imperative code at global scope:
// At the beginning of the file...
template <uint64_t N> void global_function() { global_function<N - 1>(); } // This default-case skips "gaps" in the specializations, in case __COUNTER__ is used for some other purpose.
template <> void global_function<__COUNTER__>() {} // This is the base case.
void run_global_functions();
#define global_n(N, ...) \
template <> void global_function<N>() { \
global_function<N - 1>(); /* Recurse and call the previous specialization */ \
__VA_ARGS__; /* Run the user code. */ \
}
#define global(...) global_n(__COUNTER__, __VA_ARGS__)
// ...
std::map<std::string, int> myMap;
global({
myMap["test"]=222;
// Do whatever with your global variables
})
global(myMap["Error"] = 111);
int main() {
run_global_functions();
std::cout << "Map size: " << myMap.size() << std::endl; // Show myMap has initialized correctly :)
}
global(std::cout << "This will be the last global code run before main!");
// ...At the end of the file
void run_global_functions() {
global_function<__COUNTER__ - 1>();
}
This is especially powerful once you realize that you can use it to initialize static variables without a dependency on the C runtime. This means you can generate very small executables without having to eschew non-zero global variables:
// At the beginning of the file...
extern bool has_static_init;
#define default_construct(x) x{}; global(if (!has_static_init()) new (&x) decltype(x){})
// Or if you don't want placement new:
// #define default_construct(x) x{}; global(if (!has_static_init()) x = decltype(x){})
class Complicated {
int x = 42;
Complicated() { std::cout << "Constructor!"; }
}
Complicated default_construct(my_complicated_instance); // Will be zero-initialized if the CRT is not linked into the program.
int main() {
run_global_functions();
}
// ...At the end of the file
static bool get_static_init() {
volatile bool result = true; // This function can't be inlined, so the CRT *must* run it.
return result;
}
has_static_init = get_static_init(); // Will stay zero without CRT
This answer is similar to Some programmer dude's answer, but may be considered a bit cleaner. As of C++17 (that's when std::invoke() was added), you could do something like this:
#include <functional>
auto initializer = std::invoke([]() {
// Do initialization here...
// The following return statement is arbitrary. Without something like it,
// the auto will resolve to void, which will not compile:
return true;
});

Trouble implementing min Heaps in C++

I'm trying to implement a minheap in C++. However the following code keeps eliciting errors such as :
heap.cpp:24:4: error: cannot convert 'complex int' to 'int' in assignment
l=2i;
^
heap.cpp:25:4: error: cannot convert 'complex int' to 'int' in assignment
r=2i+1;
^
heap.cpp: In member function 'int Heap::main()':
heap.cpp:47:16: error: no matching function for call to 'Heap::heapify(int [11], int&)'
heapify(a,i);
^
heap.cpp:47:16: note: candidate is:
heap.cpp:21:5: note: int Heap::heapify(int)
int heapify(int i) //i is the parent index, a[] is the heap array
^
heap.cpp:21:5: note: candidate expects 1 argument, 2 provided
make: * [heap] Error 1
#include <iostream>
using namespace std;
#define HEAPSIZE 10
class Heap
{
int a[HEAPSIZE+1];
Heap()
{
for (j=1;j<(HEAPISZE+1);j++)
{
cin>>a[j];
cout<<"\n";
}
}
int heapify(int i) //i is the parent index, a[] is the heap array
{
int l,r,smallest,temp;
l=2i;
r=2i+1;
if (l<11 && a[l]<a[i])
smallest=l;
else
smallest=i;
if (r<11 && a[r]<a[smallest])
smallest=r;
if (smallest != i)
{
temp = a[smallest];
a[smallest] = a[i];
a[i]=temp;
heapify(smallest);
}
}
int main()
{
int i;
for (i=1;i<=HEAPSIZE;i++)
{
heapify(a,i);
}
}
}
Ultimately, the problem with this code is that it was written by someone who skipped chapters 1, 2 and 3 of "C++ for Beginners". Lets start with some basics.
#include <iostream>
using namespace std;
#define HEAPSIZE 10
Here, we have included the C++ header for I/O (input output). A fine start. Then, we have issued a directive that says "Put everything that is in namespace std into the global namespace". This saves you some typing, but means that all of the thousands of things that were carefully compartmentalized into std:: can now conflict with names you want to use in your code. This is A Bad Thing(TM). Try to avoid doing it.
Then we went ahead and used a C-ism, a #define. There are times when you'll still need to do this in C++, but it's better to avoid it. We'll come back to this.
The next problem, at least in the code you posted, is a misunderstanding of the C++ class.
The 'C' language that C++ is based on has the concept of a struct for describing a collection of data items.
struct
{
int id;
char name[64];
double wage;
};
It's important to notice the syntax - the trailing ';'. This is because you can describe a struct and declare variables of it's type at the same time.
struct { int id; char name[64]; } earner, manager, ceo;
This declares a struct, which has no type name, and variables earner, manager and ceo of that type. The semicolon tells the compiler when we're done with this statement. Learning when you need a semicolon after a '}' takes a little while; usually you don't, but in struct/class definition you do.
C++ added lots of things to C, but one common misunderstanding is that struct and class are somehow radically different.
C++ originally extended the struct concept by allowing you to describe functions in the context of the struct and by allowing you to describe members/functions as private, protected or public, and allowing inheritance.
When you declare a struct, it defaults to public. A class is nothing more than a struct which starts out `private.
struct
{
int id;
char name[64];
double wage;
};
class
{
public:
int id;
char name[64];
double wage;
};
The resulting definitions are both identical.
Your code does not have an access specifier, so everything in your Heap class is private. The first and most problematic issue this causes is: Nobody can call ANY of your functions, because they are private, they can only be called from other class members. That includes the constructor.
class Foo { Foo () {} };
int main()
{
Foo f;
return 0;
}
The above code will fail to compile, because main is not a member of Foo and thus cannot call anything private.
This brings us to another problem. In your code, as posted, main is a member of Foo. The entry point of a C++ program is main, not Foo::main or std::main or Foo::bar::herp::main. Just, good old int main(int argc, const char* argv[]) or int main().
In C, with structs, because C doesn't have member functions, you would never be in a case where you were using struct-members directly without prefixing that with a pointer or member reference, e.g. foo.id or ptr->wage. In C++, in a member function, member variables can be referenced just like local function variables or parameters. This can lead to some confusion:
class Foo
{
int a, b;
public:
void Set(int a, int b)
{
a = a; // Erh,
b = b; // wat???
}
};
There are many ways to work around this, but one of the most common is to prefix member variables with m_.
Your code runs afoul of this, apparently the original in C passed the array to heapify, and the array was in a local variable a. When you made a into a member, leaving the variable name exactly the same allowed you not to miss the fact that you no-longer need to pass it to the object (and indeed, your heapify member function no-longer takes an array as a pointer, leading to one of your compile errors).
The next problem we encounter, not directly part of your problem yet, is your function Heap(). Firstly, it is private - you used class and haven't said public yet. But secondly, you have missed the significance of this function.
In C++ every struct/class has an implied function of the same name as the definition. For class Heap that would be Heap(). This is the 'default constructor'. This is the function that will be executed any time someone creates an instance of Heap without any parameters.
That means it's going to be invoked when the compiler creates a short-term temporary Heap, or when you create a vector of Heap()s and allocate a new temporary.
These functions have one purpose: To prepare the storage the object occupies for usage. You should try and avoid as much other work as possible until later. Using std::cin to populate members in a constructor is one of the most awful things you can do.
We now have a basis to begin to write the outer-shell of the code in a fashion that will work.
The last change is the replacement of "HEAPSIZE" with a class enum. This is part of encapsulation. You could leave HEAPSIZE as a #define but you should expose it within your class so that external code doesn't have to rely on it but can instead say things like Heap::Size or heapInstance.size() etc.
#include <iostream>
#include <cstdint> // for size_t etc
#include <array> // C++11 encapsulation for arrays.
struct Heap // Because we want to start 'public' not 'private'.
{
enum { Size = 10 };
private:
std::array<int, Size> m_array; // meaningful names ftw.
public:
Heap() // default constructor, do as little as possible.
: m_array() // says 'call m_array()s default ctor'
{}
// Function to load values from an istream into this heap.
void read(std::istream& in)
{
for (size_t i = 0; i < Size; ++i)
{
in >> m_array[i];
}
return in;
}
void write(std::ostream& out)
{
for (size_t i = 0; i < Size; ++i)
{
if (i > 0)
out << ','; // separator
out << m_array[i];
}
}
int heapify(size_t index)
{
// implement your code here.
}
}; // <-- important.
int main(int argc, const char* argv[])
{
Heap myHeap; // << constructed but not populated.
myHeap.load(std::cin); // read from cin
for (size_t i = 1; i < myHeap.Size; ++i)
{
myHeap.heapify(i);
}
myHead.write(std::cout);
return 0;
}
Lastly, we run into a simple, fundamental problem with your code. C++ does not have implicit multiplication. 2i is the number 2 with a suffix. It is not the same as 2 * i.
int l = 2 * i;
There is also a peculiarity with your code that suggests you are mixing between 0-based and 1-based implementation. Pick one and stick with it.
--- EDIT ---
Technically, this:
myHeap.load(std::cin); // read from cin
for (size_t i = 1; i < myHeap.Size; ++i)
{
myHeap.heapify(i);
}
is poor encapsulation. I wrote it this way to draw on the original code layout, but I want to point out that one reason for separating construction and initialization is that it allows initialization to be assured that everything is ready to go.
So, it would be more correct to move the heapify calls into the load function. After all, what better time to heapify than as we add new values, keeping the list in order the entire time.
for (size_t i = 0; i < Size; ++i)
{
in >> m_array[i];
heapify(i);
}
Now you've simplified your classes api, and users don't have to be aware of the internal machinery.
Heap myHeap;
myHeap.load(std::cin);
myHeap.write(std::cout);

How to create a std::initializer_list from variable data

I'm trying to create a std::discrete_distribution object using data passed into a class constructor. I know how to create this using static data, but cannot figure out how using variable data (cleanly). What I have now "works", but is painful. Is there a more appropriate way of doing this?
The distInit = { distArray[0], ... }; line is the problem.
#include <iostream>
#include <iomanip>
#include <initializer_list>
#include <map>
#include <random>
class Die {
private:
int loadSide;
double loadAmount;
std::mt19937 generator;
std::discrete_distribution<> distribution;
std::initializer_list<double> distInit;
std::array<double, 7> distArray;
public:
Die( int loadSide, double loadAmount ) : loadSide(loadSide), loadAmount(loadAmount) {
distArray.fill( 1 );
distArray[0] = 0;
distArray[this->loadSide] = this->loadAmount;
distInit = { distArray[0], distArray[1], distArray[2], distArray[3], distArray[4], distArray[5], distArray[6] };
distribution.param( distInit );
};
int roll( ) {
return distribution( generator );
};
};
const int ROUNDS = 10000;
int main() {
Die* die = new Die( 5, 20 );
std::map<int, int> m;
for(int n=0; n < ROUNDS; n++) {
m[die->roll()]++;
}
for(auto p : m) {
std::cout << p.first << " generated " << std::setiosflags(std::ios::fixed) << std::setprecision(2) << (float) p.second / ROUNDS << " times\n";
}
}
I may not be asking the right question, which I will apologize in advance for if so. This is a strong possibility as I'm surprised I'm unable to find any (apparently) related hits on this subject.
My compiler is g++-mp-4.8 (MacPorts gcc48 4.8-20130411_0) 4.8.1 20130411 (prerelease)
Command line /opt/local/bin/g++-mp-4.8 -std=c++11 test.cpp -o test
If you have variable data, you should be using the discrete_distribution constructor taking a pair of iterators:
template< class InputIt >
discrete_distribution( InputIt first, InputIt last );
You shouldn't be trying to construct the param_type directly; instead use a helper function to construct your distribution:
class Die {
private:
std::mt19937 generator;
std::discrete_distribution<> distribution;
static std::discrete_distribution<> makeDistribution(
int loadSide, double loadAmount )
{
std::array<double, 7> distArray;
distArray.fill( 1 );
distArray[0] = 0;
distArray[loadSide] = loadAmount;
return {std::begin(distArray), std::end(distArray)};
}
public:
Die( int loadSide, double loadAmount ) :
generator{ },
distribution{ makeDistribution( loadSide, loadAmount ) }
{}
int roll( ) {
return distribution( generator );
}
};
std::initializer_list only intended for use as a temporary object (function argument) or local variable. It's not a container and it doesn't own anything; it's an accessor to an anonymous, temporary array.
The Standard includes an example similar to your code, §8.5.4/6, which mentions
the initializer_list object is initialized in a constructor’s ctor-initializer, so the array persists only until the constructor exits, and so any use of the elements of i4 after the constructor exits produces undefined behavior.
In your case, it's the body of the constructor, not a ctor-initializer preceding the body, but the story is the same. It's just dumb luck that your program is working for now.
To store the distribution in the object, use std::array or std::vector. array is more efficient but it doesn't support arr = { … } syntax. (There are a few simple alternatives.) vector does support your syntax using braces and the = operator; this support uses an implicit std::initializer_list.
I don't know any better way to create a std::initializer_list from a container like std::array other than the one shown in the OP.
However, for the original problem, namely, passing the parameters to the distribution, I can suggest something simpler.
typedef std::discrete_distribution<>::param_type param_type;
distribution.param(param_type(distArray.begin(), distArray.end()));
The standard says that distributions must provide a type member param_type (which is the type of argument taken by param()) but doesn't specify it. However, [rand.req.dist] says that
For each of the constructors of D [the distribution type] taking arguments corresponding to parameters of the distribution, P [param_type] shall have a corresponding constructor subject to the same requirements and taking arguments identical
in number, type, and default values.
Well, it turns out that std::discrete_distribution<> has a constructor taking iterators pointing to the range of parameters. Therefore, whatever std::discrete_distribution<>::param_type is, it must have a similar constructor. Therefore, I'm suggesting creating a param_type from distArray.begin() and distArray.end() and pass it to distribution.param().
A side note: You no longer need std::initializer_list<double> distInit; in your class. It seems to me that you don't need std::array<double, 7> distArray as a class member either (it could be a local variable in Die's constructor).

Changing int value from a class function

I have a shape class that I initialize from my main program and give the parameters in the constructor.
Shape *cusomShape = new CustomShape(float radius, float origin)
The shape class has some functions such as rollover and more.
When the rollover function inside the shape class is fired, I want to change a certain int value in the main program. This might similar to firing of an event that changes the value when the rollover function is fired, but I am not sure how to do that in C++. If at all, events is the ideal approach here, it would great to see a short example coming.
If using the event is not the correct, what would the ideal way to go about this?
I think what you need is to pass a value by pointer or reference to the function in Shape and then modify it. If the function is called not from main but from somewhere else passing the pointer is the better option you have. First pass the pointer to the class and store it using another method and then each time rollover is called make use of it.
EDIT: example:
class CustomShape {
void storePointer(int* _value) {
value = _value;
}
void rollover() {
.. do stuff
*value++; // for instance
... do stuff
}
int * value;
}
int main() {
int a;
CustomShape cs;
cs.storePointer(&a);
....
cs.rollover();
....
return 0;
}
Pass a reference to the variable in the constructor and save that reference. Change the value when needed.
I would suggest passing a reference to the variable to the member function that needs to change its value. Storing a reference in a class couples the Shape class to the reference. This means that each time you want to use the Shape, without updating the integer, you cannot, since the Shape constructor will expect a reference/pointer to the int as an argument (the Shape class will store the pointer/reference as an attribute). Passing a reference/pointer to the member function promotes Low Coupling.
#include <iostream>
class Shape
{
double shapeValue_;
public:
Shape (double value)
:
shapeValue_(value)
{}
void fireFunction(int& updateMe)
{
updateMe = 123;
}
};
using namespace std;
int main()
{
int update;
cout << update << endl;
Shape s(4.5);
s.fireFunction(update);
cout << update << endl;
return 0;
};
And in this case, you have an option for a main program that doesn't involve shape object calling on fireFunction:
int main()
{
Shape s(4.5);
// Main program that doesn't use fireFunction.
return 0;
};
In this case, if you have member functions changing input arguments, you should take on a style for defining such functions: e.g. make sure that the variable that gets changed by the member function is always the first input argument in its declaration.
If you want complex objects to communicate updates between each other, you can make use of the Observer Pattern.