Cannot make unordered_map work - c++

I have written fairly simple code to check out unordered_pair
// unordered_map example
#include <iostream>
#include <unordered_map>
int main (){
std::unordered_map<double, double> mymap = {
{5,2.3},
{7,34},
{4,12}
};
std::cout<<":::: unordered_map ::::"<<std::endl;
std::cout<<"5 ->"<<mymap[5]<<std::endl;
std::cout<<"7 ->"<<mymap[7]<<std::endl;
std::cout<<"4 ->"<<mymap[4]<<std::endl;
std::cout<<"Done ! ";
return 0;
}
I get the following error
unordered_map.cpp:5:37: error: non-aggregate type 'std::unordered_map<double, double>' cannot be initialized with an initializer list
std::unordered_map<double, double> mymap = {
^ ~
1 error generated.
Compilation failed
I am working on OSX and using geany.
Build command in Geany is :
g++ -Wall -c "%f"

unordered_map was introduced in the C++11 standard. If your g++ version supports it, you can enable c++11 standard with option -std=c++11
is there a way to use associative containers in older standards
std::map is an associative container. It exists in all c++ standards.
I was trying to use unordered_map because it is faster than map
unordered_map is faster in some cases. map is faster in other cases. Don't assume one way until you have measured.
However, using map without -std=c++11 still gives me same error as above
That's because you use list initialization which also requires c++11.
The old way of initializing a map:
std::map<int, int> m;
m[1] = 3;
m[2] = 2;
m[3] = 1;
Boost has a neat template for similar syntax to list initialization:
map<int,int> next = map_list_of(1,2)(2,3)(3,4)(4,5)(5,6);

Related

Error: non-aggregate type 'vector<int>' cannot be initialized with an initializer list. How to solve?

I have written the following code in which I have initialise the vector with along with declaration of vector. Just like array but it is throwing the following error :-
CODE IS :-
# include <iostream>
# include <vector>
using namespace std;
int main()
{
vector <int> v = {1,2,3,4,5};
vector <int> :: iterator it ;
it = v.begin();
cout<< (*it) <<endl;
return 0;
}
THE OUTPUT I RECEIVED IIN TERMINAL IS:-
apple#Apples-MacBook-Air Iterators % cd "/Users/apple/Desktop/CODE/Iterators/" && g++ iteratorsBasics.cpp -o iterat
orsBasics && "/Users/apple/Desktop/CODE/Iterators/"iteratorsBasics
iteratorsBasics.cpp:8:18: error: non-aggregate type 'vector<int>' cannot be initialized with an initializer list
vector <int> v = {1,2,3,4,5};
^ ~~~~~~~~~~~
1 error generated.
apple#Apples-MacBook-Air Iterators %
Being the beginner I don't know how to sort this out please help.
the c++ version I checked in terminal by sawing some videos over internet is as follows:-
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: arm64-apple-darwin21.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
You are compiling agains C++98 or C++03 standard versions. Add the flag -std=c++11 (or later: c++14/c++17/c++20) to the compiler invocation and it should compile.
Before C++11 std::initializer_list and the std::initializer_list overload of the std::vector constructor did not exist.
Try compiling your code with the following compiler flag:
-std=c++11
So the command:
g++ -std=c++11 your_file.cpp

make_heap and pop_heap are OK but push_heap not

I just came across a weird problem that happens ONLY on MSVC with Clion but not on other compilers(I tried gcc on Linux and Visual Studio both no such problem, with the same code).
With these codes:
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int>v = {1,2,3,4,5};
make_heap(v.begin(), v.end());
v.push_back(6);
push_heap(v.begin(), v.end());
}
an error "In instantiation of function template specialization 'std::push_heapstd::_Vector_iterator<std::_Vector_val<std::_Simple_types<int > > >' no type named 'value_type' in 'std::indirectly_readable_traitsstd::_Vector_iterator<std::_Vector_val<std::_Simple_types<int > > >'" will then be shown
is it a bug of Clion or MSVC?
P.S.
I can still build and run it so it might not be a compiler error; (Making me even more confused)
It looks like you cannot intialize vector with the following command:
vector<int>v = {1,2,3,4,5};
Change it to:
vector<int> vect{ 1, 2, 3, 4, 5 };
Compile and run the code and see if it still has problems.
EDIT:
Some people are saying it is unlikely however look at the link:
What is the easiest way to initialize a std::vector with hardcoded elements?
If you scroll down to the second answer it says:
If your compiler supports C++11, you can simply do:
std::vector<int> v = {1, 2, 3, 4};
As you did not tell us your compiler version and environment it is very hard to determine if this is the problem. Also note that:
This is available in GCC as of version 4.4.
Unfortunately, VC++ 2010 seems to be lagging behind in this respect.
So if you are using an older version of VC++ then you are out of luck...

Unexpected error on declaring vector in c++

I'm getting an unexpectred error when I initialize a vector in the main.
I was expecting the following output:
0 1 2
I can't see why it's not working. I also writed the same code in another pc using the same compiler, and it works.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vett = {0,1,2};
for (int i : vett) {
cout << i << " ";
}
return 0;
}
error: could not convert '{0, 1, 2}' from '<brace-enclosed initializer list>' to 'std::vector<int>'|
You need to compile with at least C++11. List initialization came with C++11.
-std=c++11
You are compiling with something older than C++11, it does not support initializer list constructor.
If you are using Code::Blocks follow these steps:
Settings -> compiler -> compiler flags -> select C++11 or above

Brace Enclosed Initializer List? convert to vector

so I have a piece of code that I am attempting to test. The code is checking that a few vectors (these are elements of structs) are equivalent to known vectors at certain points, however I am running into an issue. When I attempt to compare the vector to the known vector as follows,
assert((class1.getattr().getattr().getVec(key) == {4,3,2,2}))
I get the following error:
assertAll.cpp:105:82: error: could not convert ‘{4,3,2,2}’ from ‘<brace-enclosed initializer list>’ to ‘std::vector<int>’
the rest of the code is all correct, and the lval of the assert is definitely a vector as it should be. I am compiling with the flags, -std=c++11 -Wall -Wextra -pedantic -O in g++. Does anybody know how to fix this? Is there a way to typecast the bracket enclosed initializer list to a vector, or is there a better way to do this?
Does anybody know how to fix this? Is there a way to typecast the bracket enclosed initializer list to a vector
Interestingly, I get a completely different error on Clang 3.5 and GCC 4.9.2 when I try something similar, but you can just use the initializer list syntax to construct a vector in place (not quite typecasting, I guess):
assert((class1.getattr().getattr().getVec(key) == std::vector<int>{4,3,2,2}))
I'm not sure how to do that thing where you can run code on Coliru and such, but the following code works for me on GCC 4.9.2 using g++ -std=c++11 -Wall -pedantic
#include <cassert>
#include <vector>
std::vector<int> foo() {
return {1,2,3,4};
}
template<class T>
bool is_equal(const T& a, const T& b) {
return a == b;
}
int main()
{
assert((foo() == std::vector<int>{1,2,3,4}));
assert(is_equal(foo(), {1,2,3,4}));
assert([&](std::vector<int> v) -> bool {
return foo() == v;
}({1,2,3,4}));
}
Granted, nobody in their right mind would use a lambda like that, but as you might be able to tell from the examples, you basically just need to tell the compiler that the two sides are the same type in order to get it to convert the initializer list to a vector.

Using an array as a map key is not working with C++ 11 compiler command?

I need to use an array as the map key, but I receive compiler errors indicating that the map declaration does not name a type.
I use the code in a similar question, but the code does not compile even when I have chosen the -std=c++0x or -std=c++11 compiler commands.
The code I used is:
typedef std::array<unsigned int, 3> alphabet;
std::map<alphabet, std::string> dictionary;
dictionary[{{1, 0, 8}}] = "hello";
The error is:
error: 'dictionary' does not name a type| error: expected
unqualified-id before ']' token| ||=== Build finished: 2 errors, 0
warnings (0 minutes, 1 seconds) ===|
I see little on this topic even when searching Google. I am using CodeBlocks as my IDE and chosen the compiler commands mentioned above.
I think the error may be because you're trying to assign to dictionary in file scope. As pointed out, variables should be initialized in global scope, i.e.:
std::map<alphabet, std::string> dictionary = { {{1,0,8}, "hello"} };
Otherwise, you should put it in block scope, i.e. in a main().
#include <array>
#include <map>
typedef std::array<unsigned int, 3> alphabet;
std::map<alphabet, std::string> dictionary;
int main()
{
dictionary[{{1, 0, 8}}] = "hello";
}
As a side note, it seems that the braces can be elided. You do not need two sets of braces. dictionary[{1, 0, 8}] will suffice.
How you compare the arrays for the map sort?
I guess you should supply compare method like this:
struct ltarray
{
bool operator()(const alphabet& s1, const alphabet& s2) const
{
//how you compare???
return (s1<s2);
}
};
and you need to init your map template with the compare method:
std::map<alphabet, std::string, ltarray> dictionary;