c++ how to make vector store bitsets? - c++

So basically I want to store std::bitset<128> within std::vector<>.
I have tried this:
std::vector<std::bitset<128>> myVector;
But compiler complains about invalid template parameters. How can I fix this and can I add this type into a typedef for later use?
EDIT: Indeed my compiler seems to use C++03 as its default standard and I had to use vector<bitset<128> > for this to work with current settings.

Yes it works, even with a typedef.
But note that you need c++11 (-std=c++11) to use two right adjacent angle brackets in your declaration.
#include <vector>
#include <bitset>
int main() {
typedef std::vector<std::bitset<128>> Bitset_vec;
Bitset_vec v;
return 0;
}
If you don't have support for c++11, add a space between the brackets :
typedef std::vector<std::bitset<128> > Bitset_vec;
Live example here (note the -std=c++11 option)

Related

Using std::visit on a class inheriting from std::variant - libstdc++ vs libc++

Consider the following code snippet:
struct v : std::variant<int, std::vector<v>> { };
int main()
{
std::visit([](auto){ }, v{0});
}
clang++ 7 with -stdlib=libc++ -std=c++2a compiles the code;
g++ 9 with -std=c++2a fails to compile the code, with the following error:
/opt/compiler-explorer/gcc-trunk-20180711/include/c++/9.0.0/variant:94:29:
error: incomplete type 'std::variant_size' used in nested name
specifier
inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
^~~~~~~~~~~~~~
live example on godbolt.org
Are both implementations conforming to the Standard?
If not, what implementation is correct here, and why?
[variant.visit] in C++17 doesn't use variant_size_v, but it does in the current working draft as a result of an editorial change. I don't see any indication that LWG reviewed the change before it went in, but it has looked at this part of the standard several times since then and has yet to object to it, so I'm going to postulate that it is in fact required.
Meanwhile, LWG issue 3052, which has been referred to LEWG, would explicitly require std::variant. When that issue is resolved - one way or the other - it should resolve this too.
Looks like it is a bug in gcc implementation. According to cppreference, it is called as if calling invoke on a std::get. std::get<> is defined for anything which is convertible to std::variant (since it accepts a std::variant argument by forwarding reference). Your structure is convertible to std::variant, and so std::get itself works on your structure in gcc.
The fact that the gcc implementation chose to use a std::variant_size as part of its implementation of visit is their implementation detail, and the fact that it doesn't (and shouldn't) work for your struct is irrelevant.
Conclusion: It is a bug in gcc due to an oversight in implementation.
I came across this issue as well recently. I kind of came up with a workaround which basically specialises variant_size and variant_alternative for the class that inherits from the variant..
link on godbolt
Its not pretty and it injects stuff into the std namespace. I'm not a metaprogramming expert (yet!) so its something I hacked together. Maybe someone else can improve on this?
#include <variant>
#include <string>
#include <vector>
#include <iostream>
#include <utility>
#include <type_traits>
using var = std::variant<int, bool, float, std::string>;
struct myvar : public var {
using var::var;
using var::operator=;
};
namespace std{
template<>
struct variant_size<myvar> : variant_size<var> {
};
template<std::size_t I>
struct variant_alternative<I,myvar> : variant_alternative<I,var> {
};
}
int main(){
constexpr int vs = std::variant_size<var>::value;
myvar s = std::string{"boo!"};
std::visit([](auto&& e){std::cout << e << "\n";}, s);
std::cout << vs;
}

Using std::vector does not work

Why the following code doesn't compile,
#include <vector>
using std::vector;
vector<int> v; // Error: too few template arguments, expected 2
but the same code with map (and pair, set, ...) instead of vector works?
#include <map>
using std::map;
map<int, int> m; // OK
And also this code works fine:
#include <vector>
using namespace std;
vector<int> v; // OK
I know that constructor of std::vector has two arguments (type and allocator), but why vector behaviour is so different from other containers?
UPD: I'm sorry, this is my mistake. Actually the code does compile, but CLion marks it as an error. So it is CLion's bug.
It is yet not fixed CLion bug: https://youtrack.jetbrains.com/issue/CPP-5758#u=1454575544687.
As a workaround you can try to use libstdc++ instead of libc++, see https://youtrack.jetbrains.com/issue/CPP-5758#comment=27-2389700.

C++ std::array don't work on my local compiler

I follow this example array::size, but it's don't work on my Dev C++ IDE, and I don't know why.
I tried to run on Code Blocks but it's still the same.
I think code is correct but how to fix this problem
here is my code
#include <iostream>
#include <array>
using namespace std;
void useArray()
{
array<int,4> myInts;
myInts[0]=1;
cout<<"Size of Array: "<<myInts.size();
}
int main()
{
useArray();
system("pause");
}
And this is compiler error:
std::array is C++11 only. Dev-C++ does not support C++11.
If you're just looking for options to Visual Studio this article is the right starting place: http://www.cplusplus.com/articles/36vU7k9E/
In the case that you're using a compiler that does not support C++11 (using the flag: -std=c++11) you always have the chance to use a Boost alternative.
Boost comes with the Boost Array Library which is an STL conform Array. The generated code will be similar to a C Array while having the opportinity to use additionnal methods on it e.g determinate the array size. All this basically works as the C++11 version of an Array.
It lives in the 'boost' namespace instead of 'std' therefore you need to include the following header to use it:
#include <boost/array.hpp>
You should then set a typedef declaration for the Boost Array:
typedef boost::array<std::string, 3> array;
// The 3 stands for the number of elements the array can hold
Implementing one of these Arrays is then fairly simple:
array a;

C++ error: 'unordered_map' does not name a type

I am doing everything correctly as far as I can tell and I have gotten the error message:
error: 'unordered_map' does not name a type
error: 'mymap' does not name a type
In my code, I have:
#include <unordered_map>
using namespace std;
//global variable
unordered_map<string,int> mymap;
mymap.reserve(7000);
void main {
return;
}
I don't see what can be missing here....
EDIT: when I update my declaration to
std::tr1::unordered_map<string,int> mymap;
I an able to eliminate the first error, but when I try to reserve, I still get the second error message.
EDIT2: As pointed out below, reserve must go into main and I need to compile with flag
-std=c++0x
However, there still appear to be errors related to unordered_map, namely:
error: 'class std::tr1::unordered_map<std::basic_string<char>, int>' has no member named 'reserve'
Compile with g++ -std=c++11 (my gcc version is gcc 4.7.2) AND
#include <unordered_map>
#include <string>
using namespace std;
//global variable
unordered_map<string,int> mymap;
int main() {
mymap.reserve(7000); // <-- try putting it here
return 0;
}
If you want to support <unordered_map> for versions older than c++11 use
#include<tr1/unordered_map> and declare your maps in the form :- std::tr1::unordered_map<type1, type2> mymap
which will use the technical report 1 extension for backward compatibility.
You can't execute arbitrary expressions at global scope, so you should put
mymap.reserve(7000);
inside main.
This is also true for other STL containers like map and vector.

Does std::map<key, data> in C++ support native data types like Structures?

How do I map a key to a native data type like structure?
I wrote this snipped but I couldn't compile it. Do you have any ideas on how to fix it?
#include <map>
#include <iostream>
typedef struct _list
{
int a,b;
}list;
map<int,list> test_map;
int main(void)
{
cout <<"Testing"<< endl;
}
map resides in the std:: namespace. Two possible ways to fix this:
using namespace std;
// ...
map<int, list> test_map;
or
std::map<int, list> test_map;
I prefer the second method, but it's a purely personal choice.
On a related note, there is no real limitation on what you can put in a map, aside from the fact that they must be copyable/assignable, and that the key type must have a < operator (or you can also provide a comparer functor).
EDIT: Seems like <list> is included somewhere, either in <iostream> (unlikely) or <map> (strange but not impossible). A using namespace std will cause std::list to clash with your own struct. The solution: rename your struct, or remove the using namespace and put std:: where it's needed.
Added std where required.
Renamed list to mylist to avoid clash with std::list. Avoid typenames and variable names that clash with common usage.
Now compiles OK in VS2008.
#include <map>
#include <iostream>
typedef struct _list
{
int a,b;
} mylist;
std::map<int,mylist> test_map;
int main(void)
{
std::cout <<"Testing"<< std::endl;
return 0;
}
There's no issue with using your struct in the STL containers provided it's copyable cleanly (copy constructor), assignable (implements operator=) and comparable (implements operator<).
A number of problems here:
You're missing either a using::std or std::map, so the compiler doesn't know what map<int,list> means.
Assuming you have a using namespace std declaration, your typedef list might collide with the STL collection of the same name. Change the name.
Your typedef struct _tag {...} tag; construct is an archaic holdover from the 80's. It is not necesarry, and frankly rather silly. It gets you nothing.
Here's your code fixed:
#include <map>
#include <iostream>
struct MyList
{
int a,b;
};
std::map<int,MyList> test_map;
int main(void)
{
std::cout <<"Testing"<< std::endl;
return 0;
}
map<int, _list> test_map; or don't use list(much better) as a name of structure. (You probably also have
#include <list>
...
using namespace std;
somewhere in your code.
I would try to avoid using codepad at all.
I have done a couple of tests with your code and it seems that
it is adding an implicit (and unwanted) using namespace std --it does not require you to qualify map, cout or endl.
it is (probably) including more standard headers than you might want, including #include <list>.
That means that when the compiler looks at the code it is seeing two list, your version and the one in std. Because of the using directive, both are in scope in the line where you create the map and the compiler is not able to determine which to use.
Two simple things that you can do: change the name of your type for the simple test to something other than list (ouch! the tool forcing your naming choices!) or fully qualify the use:
#include <map>
struct list {
int a,b;
};
std::map< int, ::list > the_map;
// ...
Note that codepad is adding the include by itself and the using directive, so it will also compile:
struct list {
int a,b;
};
map<int,::list> the_map;
But that piece of code is wrong
You seem to be comming from C. Try this:
#include <map>
#include <iostream>
struct list
{
int a,b;
};
std::map<int,list> test_map;
int main(void)
{
std::cout <<"Testing"<< std::endl;
return 0;
}