Compile-Time container of functors for controlling an algorithm? - c++

Suppose i want something simple like the following:
I have an core-algorithm, which randomly selects one of the specialized algorithms (specialized at compile-time) and process this algorithm. These specialized algorithms are implemented trough functors.
The question is now: how to implement a container, which is build at compile-time, where the core-algorithm can first check the size of this container ("i got 4 algorithms -> need to randomly select algorithm 0-3") and can then execute the functor in this container ("randomly chosen 2 -> process the third functor in container").
How would one implement it as simple as possible? I suppose it is possible.
Is there any connection to the curiously recurring template idiom? (wiki link)
Is there a simple way with the use of Boost::Fusion? (official doc)
Edit: All the algorithms will be used in the core-algorithm. The use pattern (random-numbers) is a runtime-decision (so i don't need compile-time-rands). The algorithm just has to know the container of functors and the size of this container for safe access.

If you want your core-algorithm to execute a specialized algorithm, there should be some kind of contract between the core-algorithm and the specialized algorithm.
If you define this contract as an interface, your container is simply a container containing pointers to these interfaces, e.g.:
class IAlgorithm
{
public:
virtual double operator()(double d) = 0;
};
typedef std::vector<IAlgorithm *> Algorithms;
Calling a random algorithm is then simply taking the size of the vector, taking a random value between zero and the size of the list (0..size-1), taking the entry at that position and calling the interface.
Alternatively, you can also use the new C++0x std::function construction, like this:
#include <functional>
typedef std::function<double(double)> Algorithm;
typedef std::vector<Algorithm> Algorithms;
Taking an algorithm is similar, you should be able to call an algorithm like this:
Algorithms myAlgorithms;
...
double myresult = myAlgorithms[2](mydouble);
This approach has the advantage that you can also use lambda's.
EDIT: This is an example that uses lambda's. It compiles and works as expected with Visual Studio 2010 (just tested this myself):
#include <iostream>
#include <vector>
#include <functional>
typedef std::function<double(double)> Algorithm;
typedef std::vector<Algorithm> Algorithms;
int main()
{
Algorithms algorithms;
algorithms.push_back([](double d)->double{return d+d;});
algorithms.push_back([](double d)->double{return d*d;});
std::cout << algorithms[0](5) << std::endl;
std::cout << algorithms[1](5) << std::endl;
}

I'm not a specialist but I think that indeed boost::fusion and/or boost::mpl are the tools you're looking for.
Your class would take an mpl container as parameter, being the list of algorithms functor types, and then would work with it at compile time.

I think an interesting subproblem is how to generate random numbers at compile-time.
Perhaps something like this :)
//compiletime_rand.h
#ifndef COMPILETIME_RAND_GENERATOR_H
#define COMPILETIME_RAND_GENERATOR_H
template <unsigned N, unsigned Seed, unsigned Modulo>
struct rand_c_impl
{
static const unsigned value_impl = (1664525 * rand_c_impl<N - 1, Seed, Modulo>::value + 1013904223) % (1ull << 32);
static const unsigned value = value_impl % Modulo;
};
template <unsigned Seed, unsigned Modulo>
struct rand_c_impl<0, Seed, Modulo>
{
static const unsigned value_impl = Seed;
static const unsigned value = value_impl;
};
#endif
//next_c_rand.h
#include BOOST_PP_UPDATE_COUNTER()
rand_c_impl<BOOST_PP_COUNTER, 0, MAX_C_RAND>::value
//main.cpp
#include <boost/preprocessor/slot/counter.hpp>
#include "compiletime_rand.h"
#include <iostream>
#define MAX_C_RAND 16
template <unsigned N>
void output_compiletime_value()
{
std::cout << N << '\n';
}
int main()
{
output_compiletime_value<
#include "next_c_rand.h"
>();
output_compiletime_value<
#include "next_c_rand.h"
>();
}
Output: 15 2

Related

How do I insert into boost::unordered_set<boost::unordered_set<int> >?

The following code fails to compile, but if I remove the commented line, it compiles and runs correctly. I was only intending to use boost because C++ doesn't provide a hash function for std::unordered_set<int> by default.
#include <iostream>
#include <boost/unordered_set.hpp>
int main() {
boost::unordered_set<boost::unordered_set<int> > fam;
boost::unordered_set<int> s;
s.insert(5);
s.insert(6);
s.insert(7);
std::cout << s.size() << std::endl;
fam.insert(s); // this is the line causing the problem
return 0;
}
Edit 1:
I want to be more clear than I was in the OP. First I know that the idea of the boost::unordered_set<> is that it is implemented with a hash table, rather than a BST. I know that anything that is to be a template type to the boost::unordered_set<> needs to have a hash function and equality function provided. I also know that by default the std::unordered_set<> does not have a hash function defined which is why the following code does not compile:
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<std::unordered_set<int> > fam;
return 0;
}
However, I thought that boost provides hash functions for all their containers which is why I believed the following code does compile:
#include <iostream>
#include <boost/unordered_set.hpp>
int main() {
boost::unordered_set<boost::unordered_set<int> > fam;
return 0;
}
So now, I'm not sure why boost code just above compiles, but the code in the OP does not. Was I wrong that boost provides a hash function for all their containers? I would really like to avoid having to define a new hash function, especially when my actual intended use is to have a much more complicated data structure: boost::unordered_map<std::pair<boost::unordered_map<int, int>, boost::unordered_map<int, int> >, int>. It seems like this should be a solved problem that I shouldn't have to define myself, since IIRC python can handle sets of sets no problem.
An unordered_set (or _map) uses hashing, and requires a hash operator to be defined for its elements. There is no hash operator defined for boost::unordered_set<int>, therefore it cannot put such a type of element into your set.
You may write your own hash function for this. For example, this is a typical generic hash approach, though you may want to customize it for your particular data. If you drop this code into your example, it should work:
namespace boost {
std::size_t hash_value(boost::unordered_set<int> const& arg) {
std::size_t hashCode = 1;
for (int e : arg)
hashCode = 31 * hashCode + hash<int>{}(e);
return hashCode;
}
}

How to make a class with 'dynamic' data types?

In the C++ standard library, there is std::vector, and you can specify the type you want to put into a vector while declaring it.
I want to create a class which would contain a vector of either strings, or ints, or whatever I would ever need. Is it possible to do this in an easy way, or would I have to write thousands of lines in C and assembly?
If you put the data type in the declaration, you can instantiate different kinds of vectors: vector<int> myint_v; vector<string> mystring_v; etc.... but I think your asking about how to make a Generic class and GeeksForGeeks has a really good article on this.
#include <iostream>
using namespace std;
template <typename T>
class Array {
private:
T* ptr;
int size;
public:
Array(T arr[], int s);
void print();
};
template <typename T>
Array<T>::Array(T arr[], int s)
{
ptr = new T[s];
size = s;
for (int i = 0; i < size; i++)
ptr[i] = arr[i];
}
template <typename T>
void Array<T>::print()
{
for (int i = 0; i < size; i++)
cout << " " << *(ptr + i);
cout << endl;
}
int main()
{
int arr[5] = { 1, 2, 3, 4, 5 };
Array<int> a(arr, 5);
a.print();
return 0;
}
That's just an example of using a template to declare a methods in a class. Hopefully that helps. Let me know.
C++ has variant and any. Variant supports a fixed list of alternative types; any supports any type of object that can be copied.
Now, any is really tricky to use right; in order to get back your data, you have to know what type of data (exactly) is in the any. And often variant is all you need.
If your goal is something akin to a json structure, well there are plenty of implementations of that.
Yes you can do via some sort of manipulation. Easiest method so far i have would be using std::pair<type1,type2> method. I will initiliaze with string and double which would be able to hold most of the things you need. String can hold single character to whole text and double pretty much same thing for the number.
Easiest way is,
vector<pair<type1,type2>> vector_name;
Then push each value via make_pair method
vector_name.push_back(make_pair(type1 Value, type2 Value));
When accessing it .first is for type1 and .second would be for type2. You can see more in the code below
#include <iostream>
#include <vector>
#include <utility>
#include <string>
using namespace std;
int main(){
vector<pair<string, double>> mypair;
mypair.push_back(make_pair("HelloWorld!", 8.2021));
mypair.push_back(make_pair("!", 8));
for(auto &&i:mypair){
cout << i.first << " " << i.second << "\n";
}
return 0;
}
I want to add a major difference. std::variant is a compile time feature where std::any is runtime.
Generally, what you want is std::any. Variant is a type safe union which somehow breaks what the original union was designed for (to overlook types at runtime as well).
The benefit of std::any is that your don't have to change often a type which can contain a std::any instead of constantly changing the data (and, for example, to recompile the entire precompilation headers). The drawback is that you have to ensure that it contains the type you want, or you get an exception when using std::any_cast. There is added overhead as well.
The final advice is to avoid using any of the two, unless there is a good reason. There are safer ways to use multiple types (polymorphism). As said, your can also put your data inside an object like json or XML.

Converting a struct to an array

As programming becomes more complex, and the need to perform operations on struct data becomes visible. Is there a conversion method for converting a struct type into an array of its members such that:
struct FooDesc Foo{
int num_Foo;
int num_Bar;
int GreenFoo;
};
can be represented by:
int Bar[2];
Or better, dynamically as:
vector<int> Bar;
The goal is to convert or re-represent the data struct as an iteratable form, without the excessive use of the assignment operator.
You could use unnamed structs to make a hybrid struct where its member could be treated as an array:
struct Foo {
union {
struct {
int x;
int y;
int z;
};
struct {
int array[3];
};
};
};
LIVE DEMO
Note however, that unnamed struct comes from C11 and its not a standard C++ feature. It is supported as an extension though by GCC as well Clang.
If your structs are POD then you might consider using std::tuple instead of structs. You could then use various template facilities to work through the members of the tuple.
Here is a simple example that prints the elements of a tuple - using boost::fusion::tuple instead of the std::tuple since it has many more tuple-manipulating facilities available:
#include <boost/fusion/tuple.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <iostream>
struct Printer {
template<typename T>
void operator()(const T &t) const {
std::cout << t << std::endl;
}
};
int main(int argc, const char * argv[])
{
boost::fusion::tuple<int, int, int, int, float> t =
boost::fusion::make_tuple(3, 5, 1, 9, 7.6f);
boost::fusion::for_each(t, Printer());
return 0;
}
You could include these in unions with the struct but you'd want to do some testing to ensure proper alignment agreement.
The upside is that these manipulations are very fast - most of the work is done at compile time. The down-side is that you can't use normal control structs like indexing with runtime indices - you'd have to build an abstraction layer around that as the normal get<i>(tuple) accessor requires that i be a compile time constant. Whether this is worth the complexity depends strongly on the application.
How about:
vector <Foo> Bar;
You can then add instances of your struct and then access each element as desired, using an array-like format.
See this related question for further information:
Vector of structs initialization
Upon re-reading your question a few times, I think I mis-understood your intent and answered the "wrong question". You can make an array of your struct as mentioned above and index it as an array, but I don't believe it is quite as simple as that to make each struct element a different element of an array. If you are looking to make an array of structs, my answer should help. If you are looking to make each element of your struct an element of your array, 40two's answer should help you out.

How can I sort a string using C++ library function or STL?

char word[100],p[100],result[4][100];
I want to sort the result[4][100] alphabetically. for example
result[0]="adbs";
result[1]="aacs";
result[2]="abef";
result[3]="abbm";
after sort it will be:
result[0]="aacs";
result[1]="abbm";
result[2]="abbm";
result[3]="adbs";
how can I do this using library function or STL. thanks in advance,
What about making result an array of std::string instead and sorting that:
std::string result[4];
std::sort(result, result + (sizeof(result) / sizeof(result[0])));
Mark B's answer is the C++ way to do things.
If you are stuck with the raw character arrays, you might be better off with a C-style approach.
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <iostream>
typedef int (*Comparator)(const void *, const void *);
int main() {
const std::size_t cWords = 4;
char result[cWords][100] = { "az", "ax", "aa", "ab" };
std::qsort(result, cWords, sizeof(result[0]),
reinterpret_cast<Comparator>(std::strcmp));
for (std::size_t i = 0; i < cWords; ++i) {
std::cout << result[i] << std::endl;
}
return 0;
}
The approach is essentially the same, but the details differ.
qsort takes void pointers, the type size, and a comparison function (that also uses void pointers) to implement a sort on any kind of data type.
std::sort uses templates to handle the type-specific details, so you can work at a higher level of abstraction and also get better type-safety. But this can be harder to get right when you don't have a real type but just a fixed-length character array. The std::sort approach can potentially be faster, since the compiler has the chance to inline the comparison function.

Sort an array of std::pair vs. struct: which one is faster?

I was wondering whether sorting an array of std::pair is faster, or an array of struct?
Here are my code segments:
Code #1: sorting std::pair array (by first element):
#include <algorithm>
pair <int,int> client[100000];
sort(client,client+100000);
Code #2: sort struct (by A):
#include <algorithm>
struct cl{
int A,B;
}
bool cmp(cl x,cl y){
return x.A < y.A;
}
cl clients[100000];
sort(clients,clients+100000,cmp);
code #3: sort struct (by A and internal operator <):
#include <algorithm>
struct cl{
int A,B;
bool operator<(cl x){
return A < x.A;
}
}
cl clients[100000];
sort(clients,clients+100000);
Update: I used these codes to solve a problem in an online Judge. I got time limit of 2 seconds for code #1, and accept for code #2 and #3 (ran in 62 milliseconds). Why code #1 takes so much time in comparison to other codes? Where is the difference?
You know what std::pair is? It's a struct (or class, which is the same thing in C++ for our purposes). So if you want to know what's faster, the usual advice applies: you have to test it and find out for yourself on your platform. But the best bet is that if you implement the equivalent sorting logic to std::pair, you will have equivalent performance, because the compiler does not care whether your data type's name is std::pair or something else.
But note that the code you posted is not equivalent in functionality to the operator < provided for std::pair. Specifically, you only compare the first member, not both. Obviously this may result in some speed gain (but probably not enough to notice in any real program).
I would estimate that there isn't much difference at all between these two solutions.
But like ALL performance related queries, rather than rely on someone on the internet telling they are the same, or one is better than the other, make your own measurements. Sometimes, subtle differences in implementation will make a lot of difference to the actual results.
Having said that, the implementation of std::pair is a struct (or class) with two members, first and second, so I have a hard time imagining that there is any real difference here - you are just implementing your own pair with your own compare function that does exactly the same things that the already existing pair does... Whether it's in an internal function in the class or as an standalone function is unlikely to make much of a difference.
Edit: I made the following "mash the code together":
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
const int size=100000000;
pair <int,int> clients1[size];
struct cl1{
int first,second;
};
cl1 clients2[size];
struct cl2{
int first,second;
bool operator<(const cl2 x) const {
return first < x.first;
}
};
cl2 clients3[size];
template<typename T>
void fill(T& t)
{
srand(471117); // Use same random number each time/
for(size_t i = 0; i < sizeof(t) / sizeof(t[0]); i++)
{
t[i].first = rand();
t[i].second = -t[i].first;
}
}
void func1()
{
sort(clients1,clients1+size);
}
bool cmp(cl1 x, cl1 y){
return x.first < y.first;
}
void func2()
{
sort(clients2,clients2+size,cmp);
}
void func3()
{
sort(clients3,clients3+size);
}
void benchmark(void (*f)(), const char *name)
{
cout << "running " << name << endl;
clock_t time = clock();
f();
time = clock() - time;
cout << "Time taken = " << (double)time / CLOCKS_PER_SEC << endl;
}
#define bm(x) benchmark(x, #x)
int main()
{
fill(clients1);
fill(clients2);
fill(clients3);
bm(func1);
bm(func2);
bm(func3);
}
The results are as follows:
running func1
Time taken = 10.39
running func2
Time taken = 14.09
running func3
Time taken = 10.06
I ran the benchmark three times, and they are all within ~0.1s of the above results.
Edit2:
And looking at the code generated, it's quite clear that the "middle" function takes quite a bit longer, since the comparison is made inline for pair and struct cl2, but can't be made inline for struct cl1 - so every compare literally makes a function call, rather than a few instructions inside the functions. This is a large overhead.