accessing data within nested structures - c++

I am writing a function that prints out a hash table, the structure for this
hash table is
vector< list < Entry > > and the definition of Entry is struct Entry { string key, desc; unsigned num; }; however I am getting errors when i compile this code...
void HT::hTable_print ( )
{
bool lastempty = false;
for(unsigned int i = 0; i < hsize; i++){
list<Entry>& l = hTable[i];
if(!l.empty()){//if list isnt empty
for(unsigned int x = 0; x < l.size();x++){//loop through list
if(lastempty){
cout << endl;
}
Entry e = l.front()+x;
cout << setw(4) << x << ": " << e.key << " - "
<< setw(5) << e.num << " - " << e.desc
<< endl;
}
lastempty = false;
}else{
lastempty = true;
}
}
}
I am trying to loop through the vector and allocate each list element to a variable and then loop through that list printing out the necessary information but I will get errors when I call e.key e.num and e.desc. How do i properly call the information for each Entry structure?
EDIT: Heres a few of the errors I receive when compiling:
hTable.cc:69:24: error: no match for ‘operator+’ (operand types are ‘__gnu_cxx::__alloc_traits<std::allocator<Entry> >::value_type {aka Entry}’ and ‘unsigned int’)
Entry e = l.front()+x;
/usr/include/c++/7/bits/stl_iterator.h:397:5: note: template argument deduction/substitution failed:
hTable.cc:69:25: note: mismatched types ‘const std::reverse_iterator<_Iterator>’ and ‘unsigned int’
Entry e = l.front()+x;
^
/usr/include/c++/7/bits/stl_iterator.h:1198:5: note: template argument deduction/substitution failed:
hTable.cc:69:25: note: mismatched types ‘const std::move_iterator<_IteratorL>’ and ‘unsigned int’
Entry e = l.front()+x;
^

Notice how std::list::front() returns a reference to the first element in list. What you want to do is to take std::list::begin() to have an advancable iterator, std::advance() it and then dereference it:
list<Entry>::const_iterator iter = l.begin();
advance(iter, x);
const Entry& e = *iter;
Or, as per suggestion in the comments, iterate the list via iterators in the first place
unsigned int x = 0;
for (const auto& e : l) {//loop through list
++x;
// .... stuff ...
}

Related

How to compute distance between std::vector<int>::iterator and std::vector<int>::reverse_iterator?

I tried using std::distance like this :
vi::iterator frontIter = resVec.begin();
vi::reverse_iterator backIter = resVec.rbegin();
if(std::distance(frontIter , backIter))
{
std::cout << " ! " << std::endl;
}
But the compiler gives me this error.
partion.cpp:46:39: note: candidate is:
In file included from /usr/include/c++/4.9/bits/stl_algobase.h:66:0,
from /usr/include/c++/4.9/vector:60,
from test.h:1,
from partion.cpp:1:
/usr/include/c++/4.9/bits/stl_iterator_base_funcs.h:114:5: note: template<class _InputIterator> typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator)
distance(_InputIterator __first, _InputIterator __last)
^
/usr/include/c++/4.9/bits/stl_iterator_base_funcs.h:114:5: note: template argument deduction/substitution failed:
partion.cpp:46:39: note: deduced conflicting types for parameter ‘_InputIterator’ (‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’ and ‘std::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >’)
if(std::distance(frontIter , backIter))
So how I find the distance between these two iterators. Better yet, is there a way to solve this problem without using the back_iterator, but two standard iterators ?
for(size idx = 0 ; idx < vec.size() ; ++idx)
{
if(idx == n)
{
continue;
}
if(vec[idx] < partVal) // insert in front of partVal
{
*frontIter = vec[idx];
++frontIter;
}
else // insert at back of n
{
*backIter = vec[idx];
++backIter;
}
}
Note :
using vi = std::vector<int>;
using size = std::size_t;
Any reverse iterator can be converted to its underlying forward iterator via base().
So what you want is:
std::distance(v.begin(), v.rbegin().base())
Which will give you the same result as v.size().

Reverse Iterator Arithmetic

All, I'm trying to do an O(n^2) comparison between elements in a list in reverse, so I'm using a reverse iterator.
Code follows
#include <list>
struct Element {
double a;
double b;
};
typedef std::list<Element> ElementList;
class DoStuff {
public:
DoStuff();
void removeDuplicates(ElementList & incList) const {
for(ElementList::reverse_iterator stackIter = incList.rbegin(); stackIter != incList.rend(); ++stackIter) {
bool uniqueElement = true;
for(ElementList::reverse_iterator searchIter = stackIter+1; searchIter != incList.rend() && uniqueElement; ++searchIter) {
//Check stuff and make uniqueElement = true;
}
}
}
};
int main() {
std::list<Element> fullList;
DoStuff foo;
foo.removeDuplicates(fullList);
}
I get a compile error on the searchIter creation... why...
This works, but its stupid to read:
ElementList::reverse_iterator searchIter = stackIter;
searchIter++;
for( ; searchIter != incList.rend() && uniqueElement; ++searchIter) {
}
Error below:
In file included from /usr/local/include/c++/6.1.0/bits/stl_algobase.h:67:0,
from /usr/local/include/c++/6.1.0/list:60,
from main.cpp:1:
/usr/local/include/c++/6.1.0/bits/stl_iterator.h: In instantiation of 'std::reverse_iterator<_Iterator> std::reverse_iterator<_Iterator>::operator+(std::reverse_iterator<_Iterator>::difference_type) const [with _Iterator = std::_List_iterator<Element>; std::reverse_iterator<_Iterator>::difference_type = long int]':
main.cpp:16:66: required from here
/usr/local/include/c++/6.1.0/bits/stl_iterator.h:233:41: error: no match for 'operator-' (operand types are 'const std::_List_iterator<Element>' and 'std::reverse_iterator<std::_List_iterator<Element> >::difference_type {aka long int}')
{ return reverse_iterator(current - __n); }
The syntax it + n for some iterator it and integer n requires the iterator to be a "random access iterator". List iterators do not fulfill that requirement.
To get around the "stupid to read" issue, you can use std::next:
for(ElementList::reverse_iterator searchIter = std::next(stackIter); ...
Or, with less typing:
for(auto searchIter = std::next(stackIter); ...

error: template argument 1 is invalid while declaring an iterator for vector

The following code
ifstream read("input-1.txt");
int n,u;read >> n;
vector<list<int>> adj_list (n+1);
string delimiter = "->",vertex,list;
size_t pos = 0;int count;
string::size_type sz;
for (int i=0;i<n;i++){
read >> list;
count = 0;
while((pos = list.find(delimiter))!= string::npos){
vertex = list.substr(0,pos);
if (count!=0){
adj_list[i].push_back(stoi (vertex.substr(1,vertex.length()),&sz));
}
list.erase(0,pos+delimiter.length());
count++;
}
}
read >> vertex;
u = stoi (vertex.substr(1,vertex.length()),&sz);
vector<list<int>>::iterator it1 = adj_list.begin();
while(it1!=adj_list.end()){
list<int> new_list = *it1;
list<int>::iterator it2 = new_list.begin();
while(it2!=new_list.end()){
cout << *it2 <<" ";
it2++;
}
cout << endl;
it1++;
}
cout << u << n << "u" << "n";
gives the following error
even.cpp:37:26: error: template argument 1 is invalid
vector<typename list<int>>::iterator it1 = adj_list.begin();
^
even.cpp:37:26: error: template argument 2 is invalid
even.cpp:37:39: error: qualified-id in declaration before ‘it1’
vector<typename list<int>>::iterator it1 = adj_list.begin();
^
even.cpp:38:8: error: ‘it1’ was not declared in this scope
while(it1!=adj_list.end()){
^
even.cpp:39:8: error: expected primary-expression before ‘int’
list<int> new_list = *it1;
^
even.cpp:40:8: error: expected primary-expression before ‘int’
list<int>::iterator it2 = new_list.begin();
^
even.cpp:41:9: error: ‘it2’ was not declared in this scope
while(it2!=new_list.end()){
^
even.cpp:41:14: error: ‘new_list’ was not declared in this scope
while(it2!=new_list.end()){
The vector is declared correctly to be of list of int's. But when its iterator is declared it gives the error about template arguments.
I am just using int's and not any user defined classes, then also there the error which I cannot understand. Can anyone sort this out?
The variable list declared in
string delimiter = "->",vertex,list;
is shadowing std::list, which you want to use. Use another name for the variable.

C++ Partial Sorting Errors

What I wanted to do is generate n numbers of nearly sorted value.
For example, user will enter nvalue of 1000.
It will then pass the sorting job by calling the partial sorting function.
Basically, I will just sort half of the total values.
Meaning to say, out of 1000 that has been generated..only first half or 500 values will be sorted only.
After done sorting, it shall push all the nearly sorted value into a vector.
However, I was facing some errors which I can't understand what does it mean during compilation. Can anyone help me on these? Thank you
2 following errors:
1)'partial_sort' : ambiguous call to overloaded function c:\users\mk\documents\visual studio 2013\projects\algorithm analysis\algorithm analysis\nearlysorted.cpp 49 1 Algorithm Analysis
2)IntelliSense: more than one instance of overloaded function "partial_sort" matches the argument list:
function template "void partial_sort(rand_access begin, rand_access sort, rand_access end)"
function template "void std::partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last)"
argument types are: (std::_Vector_iterator>>, std::_Vector_iterator>>, std::_Vector_iterator>>) c:\Users\Mk\Documents\Visual Studio 2013\Projects\Algorithm Analysis\Algorithm Analysis\nearlysorted.cpp 49 2 Algorithm Analysis
Code:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
template <class rand_access>//class
void partial_sort(
rand_access begin,
rand_access sort,
rand_access end
);
template <class rand_access, class BinaryPred>//overloading
void partial_sort(
rand_access begin,
rand_access sort,
rand_access end,
BinaryPred comp
);
//Function prototype
//void decrease_store(int val, vector<int> &aVec); TODO SOON
void nearlystd_store(int val, vector<int> &aVec);
int main()
{
int nvalue;
vector<int> int_vector;
cout << "How many numbers would you like to generate?\n";
cin >> nvalue;//get input from user
nearlystd_store(nvalue, int_vector);// pass user input to the function
system("pause");
return 0;
}
void nearlystd_store(int val, vector<int> &aVec)//nearly sorted function
{
vector<int>::iterator Iter;// a vector
int num;
for (int i = 0; i < val; i ++)//generate from the start till desired nvalue
{
aVec.push_back(val - i);//push into this vector
}
partial_sort(aVec.begin(), aVec.begin() + (val / 2), aVec.end());//sort half in the vector
cout << "The Output:\n";
for (Iter = aVec.begin(); Iter != aVec.end(); ++Iter)//push sorted value
{
cout << *Iter << " " << endl;//aVec.push_back(int()); --- Not sure if correct
}
}
EDITTED CODE:
Thanks to both llya & Chris for helping out
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
//Function prototype
//void decrease_store(int val, vector<int> &aVec); TODO SOON
void nearlystd_store(int val, vector<int> &aVec);
int main()
{
int nvalue;
vector<int> int_vector;
cout << "How many numbers would you like to generate?\n";
cin >> nvalue;//get input from user
nearlystd_store(nvalue, int_vector);// pass user input to the function
system("pause");
return 0;
}
void nearlystd_store(int val, vector<int> &aVec)//nearly sorted function
{
vector<int>::iterator Iter;// a vector
for (int i = 0; i < val; i ++)//generate from the start till desired nvalue
{
aVec.push_back(val - i);//push into this vector
}
partial_sort(aVec.begin(), aVec.begin() + (val / 2), aVec.end());//sort half in the vector
cout << "The Output:\n";
for (Iter = aVec.begin(); Iter != aVec.end(); ++Iter)//push sorted value
{
cout << *Iter << " " << endl;//aVec.push_back(int()); --- Not sure if correct
}
}
Let's see compilation errors (next time add it in a question!):
prog.cpp: In function ‘void nearlystd_store(int, std::vector<int>&)’:
prog.cpp:49:68: error: call of overloaded ‘partial_sort(std::vector<int>::iterator, __gnu_cxx::__normal_iterator<int*, std::vector<int> >, std::vector<int>::iterator)’ is ambiguous
partial_sort(aVec.begin(), aVec.begin() + (val / 2), aVec.end());//sort half in the vector
^
prog.cpp:49:68: note: candidates are:
prog.cpp:8:6: note: void partial_sort(rand_access, rand_access, rand_access) [with rand_access = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]
void partial_sort(
^
In file included from /usr/include/c++/4.8/algorithm:62:0,
from prog.cpp:3:
/usr/include/c++/4.8/bits/stl_algo.h:5308:5: note: void std::partial_sort(_RAIter, _RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]
partial_sort(_RandomAccessIterator __first,
^
Here compiler informs your, that it is hard to decide, which implementation of partial_sort must be called. There are two possible options, so compiler can't be sure, which one is right. You need to avoid such uncertainty. In this case you can rename wrong declaration (i.e. remove all lines from 'template //class' to '//Function prototype').
prog.cpp:43:9: warning: unused variable ‘num’ [-Wunused-variable]
int num;
^
And this is just warning. Here you declared variable num, but never use it. It is better to remove such lines from a code to simplify it.

Iterator failure while moving over equal_range in Boost MultiIndex container

I'm making some mistake with my iterators, but I can't see it yet.
I have a Boost MultiIndex container, HostContainer hmap, whose elements are boost::shared_ptr to members of class Host. All the indices work on member functions of class Host. The third index is by Host::getHousehold(), where the household member variable is an int.
Below, I'm trying to iterate over the range of Hosts matching a particular household (int hhold2) and load the corresponding private member variable Host::id into an array. I'm getting an "Assertion failed: (px != 0), function operator->, file /Applications/boost_1_42_0/boost/smart_ptr/shared_ptr.hpp, line 418" error in runtime when the household size is 2. (I can't yet tell if it happens anytime the household size is 2, or if other conditions must be met.)
typedef multi_index_container<
boost::shared_ptr< Host >,
indexed_by<
hashed_unique< const_mem_fun<Host,int,&Host::getID> >, // 0 - ID index
ordered_non_unique< const_mem_fun<Host,int,&Host::getAgeInY> >, // 1 - Age index
ordered_non_unique< const_mem_fun<Host,int,&Host::getHousehold> > // 2 - Household index
> // end indexed_by
> HostContainer;
typedef HostContainer::nth_index<2>::type HostsByHH;
// inside main()
int numFamily = hmap.get<2>().count( hhold2 );
int familyIDs[ numFamily ];
for ( int f = 0; f < numFamily; f++ ) {
familyIDs[ f ] = 0;
}
int indID = 0;
int f = 0;
std::pair< HostsByHH::iterator, HostsByHH::iterator > pit = hmap.get<2>().equal_range( hhold2 );
cout << "\tNeed to update households of " << numFamily << " family members (including self) of host ID " << hid2 << endl;
while ( pit.first != pit.second ) {
cout << "Pointing at new family member still in hhold " << (*(pit.first))->getHousehold() << "; " ;
indID = (*(pit.first) )->getID();
familyIDs[ f ] = indID;
pit.first++;
f++;
}
What could make this code fail? The above snippet only runs when numFamily > 1. (Other suggestions and criticisms are welcome too.) Thank you in advance.
I replaced the while() loop with
for ( HostsByHH::iterator fit = pit.first; fit != pit.second; fit++ ) {
cout << "Pointing at new family member still in hhold " << (*fit)->getHousehold() << "; " ;
indID = (*fit )->getID();
cout << "id=" << indID << endl;
familyIDs[ f ] = indID;
f++;
}
This seems to work.
I don't quite understand how this is a fix or why the earlier error only occurred with households of size 2. Any insight would be very welcome.
int numFamily = hmap.get<2>().count( hhold2 );
int familyIDs[ numFamily ];
How can this possibly work? This shouldn't even compile: you can't define an array with a variable number of elements, numFamily had to be a compile time constant or else you have to define familyIDs as
int *familyIDs= new int[ numFamily ];