I need a global variable in my C++ program. It is going to be a vector of bitsets. However, the size of the bitsets is determined at runtime by a function.
So basically, I would like to register the variable (in the top part of my code) and later define it properly by the function that determines the bitarrays' size.
Is there a way to do this in C++?
One way would be to use dynamic_bitset from boost:
#include <iostream>
#include <vector>
#include <boost/dynamic_bitset.hpp>
std::vector< boost::dynamic_bitset<> > bitsets;
int main() {
bitsets.push_back(boost::dynamic_bitset<>(1024));
bitsets.push_back(boost::dynamic_bitset<>(2048));
std::cout << bitsets[0].size() << std::endl;
std::cout << bitsets[1].size() << std::endl;
}
You could also use a vector<bool> instead, i.e. vector< vector<bool> > for a vector of bitsets. It is specialized to only use one bit per element.
bitsets sizes are fixed at compile time. just use static vector<vector<bool>> MyGlobalBits;
Related
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;
}
}
I have the following
The two equivalent strings bar and bartest do not map to the same value in unordered_map. How can I make this happen?
Of course they don't map to the same value, const string* is a pointer type and since you call new string twice, you end up with two separate objects that don't have memory identity (the pointers are not equal).
What's worse, you leak both of them at the end of your program.
What's (arguably) worse still, owning raw pointers and naked new calls are considered harmful in modern c++.
Luckily it's all fixed with unordered_map<string, int> - no pointers required whatsoever.
Your C++ is in fact "Java-- + C".
Remove all those silly pointers.
All you need is unordered_map<string,int> and use plain values instead of heap-allocated "news"
just do
#include <unordered_map>
#inclide <string>
#include <iostream>
int main()
{
unordered_map<string,int> mymap;
mymap["bar"] = 5;
mymap["bartest"] = 10;
std::cout << mymap["bar"] << ' ' << mymap["bartest"] << '\n';
return 0;
}
My question is rather short:
I need a vector which holds different types like:
std::vector<int,double> vec;
vec.emplace_back((int) 1);
vec.emplace_back((double) 2.0);
I tried using boost:variant, but the problem is that one has to visit/get the numbers out of the vector each time one wants to use the values.
I define initial values for the vector so the types are static and are defined at compile time. Moreover, I want to be able to iterate over them (that is why i use a vector- it could also be a map or any other container).
What I want is to use the vector entries like a int or double in the program without using boost::get or something of that kind. I think this should be possible because the type of each entry is totally defined at compile time but I do not know how to get it to work.
double d=vec[1]*3.0; //this should somehow work
int i=vec[0]*8; //this also without any get or anything
I tried using tuples, but I do not have much experience with them and it seems rather hard to iterate over them.
for(auto &elem : vec) std::cout << elem << std:endl; //this or sth. similar should also work
Any help is deeply appreciated.
You should use a tuple indeed. CPP is a strong typed language. Deal with it.
Now, if you want to iterate, consider using Boost Fusion:
Live On Coliru
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <boost/fusion/algorithm.hpp>
#include <boost/fusion/adapted/boost_tuple.hpp>
#include <boost/phoenix.hpp>
using namespace boost;
using namespace boost::phoenix::arg_names;
#include <iostream>
int main() {
tuple<int, double, std::string> demo(42, 3.1415, "hello pie universe");
fusion::for_each(demo, std::cout << arg1 << "\n");
auto& v2 = get<1>(demo);
v2 *= 10;
std::cout << "\nNew v2: " << v2 << "\n";
std::cout << "Tuple after edit: " << demo << "\n";
}
Which prints
42
3.1415
hello pie universe
New v2: 31.415
Tuple after edit: (42 31.415 hello pie universe)
I have this code:
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector <bool> v;
cin >> v[0];
return 0;
}
Why can't I do that? The compiler won't compile that, but I have other variable types in the vector, it will work just fine. What's the problem with this?
It's because std::vector<bool> is a specialization and doesn't act like a vector at all. This is widely recognized to be a major flaw in the Standard.
In order to save memory, vector<bool> stores each element as a single bit. But bits aren't individually addressable, so operator[] can't return a bool& reference connected to a bit. Instead it returns vector<bool>::reference... and cin doesn't provide function overloads to deal with this.
(juanchopanza correctly points out that your vector didn't have an element zero. But even if it did via resize or other mechanism, the fact that operator[] doesn't return a reference still gets in the way.)
At the time you call v[0], the vector has zero size, so you are accessing out of bounds. This is undefined behaviour.
Furthermore, std::vector<bool> is a specialization which has strange behaviour due to the fact that it does not hold individual bool elements. Its operator[] returns a kind of proxy object, the call to that operator may not do what you expect. It should be used with care, or not used at all.
You can solve the problem by reading a value into a local variable and then pushing it into the back of the vector, as in this working example (similar live demo here):
#include <vector>
#include <iostream>
int main()
{
std::vector<bool> v;
std::cout << std::boolalpha;
v.push_back(true);
std::cout << v[0] << std::endl;
bool b;
cin >> b;
v[0] = b;
std::cout << v[0] << std::endl;
}
This should work:
#include <iomanip>
...
bool a;
cin >> boolalpha >> a;
v.push_back(a);
(In addition to the problem mentioned by Ben Voigt, your current code isn't safe with types other than bool because your vector is empty when you're accessing v[0].)
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