I am currently trying to create a vector containing function of a class .
Here is my code :
typedef leap::float64 (DataReader::*getFonction)();
std::vector<getFonction> vec;
std::vector<getFonction>::iterator it;
vec.push_back(&DataReader::getLa);
vec.push_back(&DataReader::getLon);
for(it = vec.begin(); it<vec.end(); it++)
std::cout << *it << std::endl;
The function "get ..." (not static ) returned values ββare stored on shared resources and already initialized.
But then , they return me only the values ββ'1'.
An idea?
When you dereference it and output it, you are just printing out a representation of the function pointer, which is being implicitly converted to bool and output as 1 because it is not null.
If you want to call the function and output the return value, you need to call it on an instance:
DataReader reader;
for(it = vec.begin(); it<vec.end(); it++)
//dereference it to get member function pointer and call it on reader
std::cout << (reader.*(*it))() << std::endl;
If you are using C++11, std::function may be better suited:
using getFunction = std::function<leap::float64(DataReader&)>;
std::vector<getFunction> vec;
std::vector<getFunction>::iterator it;
vec.emplace_back(&DataReader::getLa);
vec.emplace_back(&DataReader::getLon);
DataReader reader;
for(it = vec.begin(); it<vec.end(); it++)
std::cout << (*it)(reader) << std::endl;
Related
I'm trying to print elements of a vector of list pair in a hash-table program in C++.
If I use the C++11 auto it's working but if i use a iterator
for (vector<int>::iterator i = arr_Hash[i].begin(); i != arr_Hash[i].end(); ++i)
//for (auto index = arr_Hash[i].begin(); index != arr_Hash[i].end(); index++)
{
cout << i->second;
cout << " ";
}
Error list: https://i.imgur.com/rDejBGG.png
How can I use the iterator here?
vector<int>::iterator i = arr_Hash[i].begin()
You're reusing the variable i here. Call it something else.
std::cout << i->second;
i is a std::vector<int>::iterator. Dereferencing it gives you an int&, which has no second member. You probably just want std::cout << *i;
The iterator for arr_Hash[i] needs to be on the same type as the vector.
Namely, if the type of arr_Hash[i] is vector<pair<int,int>> then it's iterator needs to be vector<pair<int,int>>::iterator.
Howerver, you should Prefer a range-for-statement to a for-statement when there is a choice.
for (auto& e : arr_Hash[i])
cout << i->second << " ";
I am having issues loading and printing my map-map-vector data structure. I think it's on the printing side, since I am not 100% sure how to use iterators.
I created and loaded the data into the structure to store my data here:
(I created inner_test and myvector because it looked like I needed them for the iterators. I'm not sure how the iterators know that inner_test and myvector are part of test though.)
map<int, map<string, vector<string>>> test;
map<string, vector<string>> inner_test;
vector<string> myvector;
ifstream thisfile;
const char *file1 = argv[1];
thisfile.open(file1);
string filler;
while( thisfile >> filler ){
string sortedFiller = filler;
sort(sortedFiller.begin(), sortedFiller.end());
test[filler.length()][sortedFiller].push_back(filler);
}
thisfile.close();
I tried to print it with this, but I don't think I quite understand what I'm doing here.
map<int, map<string, vector<string>>>::iterator itr1;
map<string, vector<string>>::iterator itr2;
vector<string>::iterator itr3;
for(itr1 = test.begin(); itr1 != test.end(); itr1++){
cout << itr1->first;
for(itr2 = inner_test.begin(); itr2 != inner_test.end(); itr2++){
cout << itr2->first;
for(itr3 = myVector.begin(); itr3 != myVector.end(); itr3++){
cout << *itr3;
}
}
cout << endl;
}
Your inner_test, and my_vector variables are empty containers, and are unrelated to the actual std::map, you want to print, in any way. This is one of the examples how can you print multidimensional container:
// auto type automatically defines itself as a return type of test.begin ()
for(auto itr1 = test.begin(); itr1 != test.end(); itr1++)
{
cout << itr1->first << ' '; // Add space to separate entries on the same line
// itr1->second represents map<string, vector<string>> stored in test.
for(auto itr2 = itr1->second.begin (); itr2 != itr1->second.end (); itr2++)
{
cout << itr2->first << ' ';
// itr2->second represents vector<string> stored in map<string, vector<string>> which is stored in test.
for(auto itr3 = itr2->second.begin(); itr3 != itr2->second.end(); itr3++)
{
cout << *itr3 << ' ';
}
}
cout << endl;
}
Use auto to deduce type of iterators automatically like for(auto itr1 = container.begin(); ....
Then, before second loop, add const auto& inner_test = itr1->second; and iterate over your nested map like you did.
Similarly, before third loop, add const auto& myVector = itr2->second;.
What is going on here.
In C++ it's possible to overload * and -> operators. Iterators do that.
When you iterate over std::map, iterator points std::pair of references to key and value. Pair has first and second fields which are, in this case, references to key and value respectively.
Also, use .cbegin() and .cend() -- const iterators -- if you don't want to alter data in map.
I have looked for this and found something here: Variable not printing on iteration but I'm not sure if that necessarily applies.
What I have going on is my program correctly prints all values when I call it like this:
for (int i = 0; i < SampleVec.Matchups().size(); ++i){
std::cout << SampleVec.Matchups()[i] << std::endl;
}
or when I call it like this:
std::vector<int> temp;
temp = SampleVec.Matchups();
for (std::vector<int>::const_iterator iter = temp.begin(); iter != temp.end(); iter++){
std::cout << *iter << std::endl;
}
but when I write it like this
for (std::vector<int>::const_iterator iter = SampleVec.Matchups().begin(); iter != SampleVec.Matchups().end(); iter++){
std::cout << *iter << std::endl;
}
the first two values show up as a 0 and the rest print correctly. In the link I posted they talk about stripping newlines from the input, but I don't know if that applies here or even how to do that. I can post full code if needed to run and see the functionality in action.
for (std::vector<int>::const_iterator iter = SampleVec.Matchups().begin(); iter != SampleVec.Matchups().end(); iter++){
std::cout << *iter << std::endl;
}
begin() returns the iterator of the beginning of a temporary std::vector returned by Matchups(). At the moment of using iter it's a dangling iterator because the temporary has been destroyed and thus you have Undefined Behaviour.
You have to store the result before trying to access it through an iterator like you do in example 2.
How to iterate through the contents of map["a"] to retrieve call and call1 ?
std::vector<std::string> point
std::map<std::string, point> alloc
map["a"] = call, call1
map["i"] = call
I have tried using for loop using map iterator and inside that for loop another for loop on the vector and then checking whether the value of map iterator map equals "a" but keep getting an error.
I think you are misunderstanding some syntax and of the programming language and the semantics of the standard library containers a little bit. I will explain what I think you are doing wrong.
First thing is that you have a vector of string objects called point, this is an object not a type. An object is a variable of a type, for example
string name = "curious";
Here name is an object of type/class string, so you cannot type in point as the template parameter to the map, you have to type in a type. So that should be a string.
Second thing is that you are using the comma operator, I am not sure if you knew that you were doing that. The comma operator works as follows
#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;
int main() {
cout << ("Hello", "World") << endl;
return 0;
}
^ this will generate a compiler error because the "Hello" is not used but the point is that the comma operator evaluates the first part of the expression and then returns the thing on the right; so this will print
World
Third thing is how you iterate through the map. When you iterate through a std::map in C++ you are actually iterating through a series of std::pairs so the following code
#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;
#include <map>
using std::map;
int main() {
map<string, int> map_string_int {{"curious", 1}, {"op", 2}};
for (auto iter = map_string_int.begin(); iter != map_string_int.end();
++iter) {
cout << iter->first << " : " << iter->second << endl;
}
return 0;
}
will produce the following output
curious : 1
op : 2
the keys will be ordered alphabetically because they are stored in a binary search tree (https://en.wikipedia.org/wiki/Binary_search_tree)
Now I think you wanted to have a map from string objects to vectors, so you would structure your code as such
std::vector<string> point
std::map<string, std::vector<string>> alloc;
alloc["a"] = {"call", "call1"};
alloc["i"] = {"call"};
and you would iterate through this like so
for (auto iter = alloc.begin(); iter != alloc.end(); ++iter) {
cout << iter->first << " : " << iter->second << endl;
}
You would iterate through alloc["a"] like so
// sanity check
assert(alloc.find("a") != alloc.end());
for (auto iter = alloc["a"].begin(); iter != alloc["a"].end(); ++iter) {
cout << *iter << endl;
}
Hope that helped!
I assume you mean std::multimap instead of std::map, based on your use case (multiple values under the same key). It's in the same <map> header.
std::multimap<std::string, int> map;
map.insert(std::make_pair("first", 123));
map.insert(std::make_pair("first", 456));
auto result = map.equal_range("first");
for (auto it = result.first; it != result.second; ++it)
std::cout << " " << it->second;
Reference: std::multimap::equal_range
This should do what you want if I understand correctly.
std::vector<string> point = { "Hello", "World" };
std::map<std::string, decltype(point)> my_map;
//if you dont wan't to use decltype (or cant):
//std::map<std::string, std::vector<std::string>> my_map;
my_map["A"] = point;
my_map["B"] = { "Something", "Else" };
//this will iterate only trought my_map["A"]
for (const auto &vector_val : my_map["A"])
std::cout << vector_val << std::endl;
//this will iterate trought the whole map
for (const auto &map_pair : my_map)
{
std::cout << "map: " << map_pair.first << std::endl;
for (const auto &vector_val : map_pair.second)
std::cout << vector_val << std::endl;
std::cout << "---------------------------------" << std::endl;
}
I'm curious about knowing what is more suitable in such situations i.e multimap or map_of_vectors .
If sequencially someone want to iterate vector associated to a particular/all keys in map
what will be more efficient/optimal.
map<string ,vector<string>> mp;
// initialize your map...
for(auto itr=mp.begin(); itr!=mp.end() ;itr++)
for(auto itr2=itr->second.begin(); itr2!=itr->second.end() ;itr2++)
cout<<*itr2
for particular key just change first loop as stated down
auto itr=mp.find(key);
sorry if my question is to newbish, but i cant find a solution.
i have a class named Transition that have a map called inNext, and i want to print this Transition object, but i get an error about "cant find the begin or end members" (from map class)
class Transition{
public:
Transition():inNext(){};
~Transition(){};
map<string, string>& getTransition(){
return inNext;
}
void setTransition(string a, string b){
inNext.insert(pair<string,string>(a,b));
}
void printTransition(Transition a){
map <string, string>::iterator it;
for(it = a.begin(); it != a.end(); it++){
cout << (*it).first << ","<<(*it).second << endl;
}
}
private:
map<string, string> inNext;
};
Your method is weird: It's a member function and it takes another instance of Transition (and even copies it for no reason) as an argument. You probably want
void print() {
// you want to print the content of the map inNext:
for(map <string, string>::iterator it = inNext.begin(); it != inNext.end(); it++) {
cout << it->first << "," << it->second << endl;
}
}
which is called like this:
Transition myTransition = ...;
myTransition.print();
begin and end are members of std::map not of your class. You need to call a.inNext.begin() and a.inNext.end().