I have in a C++ class the following :
I want to use an iterator to have an element of the questions list at a time by calling the getNextQuestion() function after checking if the iterator is still valid by calling isValid(). It gives me the following terrible error :
passing ‘const iterator {aka const std::_List_iterator<domain::Question>}’ as ‘this’ argument of ‘std::_List_iterator<_Tp>::_Self&
std::_List_iterator<_Tp>::operator++() [with _Tp = domain::Question,std::_List_iterator<_Tp>::_Self =
std::_List_iterator<domain::Question>]’ discards qualifiers [-fpermissive]
#ifndef TESTREPOSITORY_H_
#define TESTREPOSITORY_H_
#include <iostream>
#include <iterator>
#include <list>
#include <algorithm>
#include <fstream>
#include "../domain/question.h"
using namespace domain;
namespace repository{
template<class T>
class TestRepository{
std::string file;
std::list<T> questions;
typename std::list<T>::iterator it;
public:
TestRepository(std::string& file=""):file(file){
this->questions = this->getQ();
this->it = this->questions.begin();
};
std::list<T> getQ() const{
std::list<T> listq;
using namespace std;
string line;
std::ifstream fin(file.c_str());
while(fin.good()){
Question q;
fin >> q;
listq.push_back(q);
}
fin.close();
return listq;
}
const bool isValid() const{
return this->it != this->questions.end();
}
const T getNextQuestion() const{
T q = (*this->it);
++this->it;
return q;
}
};
}
#endif /* TESTREPOSITORY_H_ */
Here is the code where I call these funcitons,maybe here is the problem coming from :
#include "TestController.h"
#include "../domain/test.h"
#include <iostream>
#include <list>
#include <iterator>
namespace controller{
TestController::TestController(repository::TestRepository<domain::Question>* repo,int testId){
this->repo = repo;
this->testId = 0;
}
const test TestController::getCurrentTest() const{
test test(this->testId,0,0);
return test;
}
const bool TestController::isValid() const{
return this->repo->isValid();
}
const Question TestController::getNextQuestion() const{
return this->repo->getNextQuestion();
}
}
Here:
const T getNextQuestion() const{
T q = (*this->it);
++this->it;
return q;
}
You are changing the field it and you're not supposed to, because the method is const. If you want to use const only in the meaning that your "repository" is not modified, but its internal iterator is irrelevant you can use the mutable keyword:
mutable typename std::list<T>::iterator it;
You are trying to modify a member in a const member function, which is forbidden (thats the point of const member functions) :
const T getNextQuestion() const{
T q = (*this->it);
++this->it; // << Here
return q;
}
This method should be non const, or consider having your member iterator be mutable :
mutable typename std::list<T>::iterator it;
Related
The code was as below
#include <set>
#include <iostream>
#include <string>
#include <memory>
using namespace std;
class Quote {
public:
int getnum() {
return num;
}
private:
int num;
};
class basket {
public:
void add_item(const shared_ptr<Quote> &b) {
setQuo.insert(b);
}
private:
static bool compare(shared_ptr<Quote> &l, shared_ptr<Quote> &r) {
return l->getnum() < r->getnum();
}
multiset<shared_ptr<Quote>, decltype(compare)*> setQuo{compare};
};
int main()
{
cout << "start" << endl;
}
I found thatsetQuo.insert(b);will lead complie error. Complie error was as below
*/usr/include/c++/7/bits/stl_tree.h:2069:51: error: binding reference of type ‘std::shared_ptr<Quote>&’ to ‘const key_type {aka const std::shared_ptr<Quote>}’ discards qualifiers
__x = _M_impl._M_key_compare(__k, _S_key(__x)) ?*
*/usr/include/c++/7/bits/stl_tree.h:1750:10: error: binding reference of type ‘std::shared_ptr<Quote>&’ to ‘const std::shared_ptr<Quote>’ discards qualifiers*
The code was looks right for me, this question is really confused me.
Your compare function is not supposed to change the elements it's comparing so take the arguments by const&:
static bool compare(const shared_ptr<Quote> &l, const shared_ptr<Quote> &r) {
return l->getnum() < r->getnum();
}
Demo
I'm trying to create a map with a custom key, which is an object's pointer address, as mentioned.
I need the address because for now it's the only relevant way to compare between two objects.
from what i understood, the proper way of doing this is by using const char* as key
here is the typedef :
typedef __gnu_cxx::unordered_map<const char*, std::string> TargetsTags;
I'm a bit confused about the following:
how do I create the operator() ?
This is what i used for std::string:
namespace __gnu_cxx {
template<>
struct hash<std::string>
{
hash<const char*> h;
size_t operator()(const std::string &s) const
{
return h(s.c_str());
};
};
}
What about const char*?
And is this the correct way of doing this?
The working example using c++11:
#include <iostream>
#include <unordered_map>
#include <string>
#include <functional>
using namespace std;
class myhash {
public:
size_t operator() (const char *val) const {
return std::hash<std::string>()(val);
}
};
class myequal {
public:
bool operator()(const char *val1, const char *val2) const{
return std::string(val1) == std::string(val2);
}
};
int main() {
std::unordered_map<const char*, string, myhash, myequal> mymap;
mymap["abc"] = "abcd";
mymap["cba"] = "dcba";
std::cout << mymap["abc"] << std::endl;
return 0;
}
The following code won't compile because of "error: no matching function for call to ‘mem_fun_ref()’" (gcc version 4.4.6).
#include <vector>
#include <string>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
class toto
{
char v[10];
public:
toto(char* t) { memcpy(v, t, 9); }
bool test(const char* var) const { return !strncmp(var, v, 9); }
bool test(const string& var) const { return test(var.c_str()); }
};
int main()
{
vector<toto> t;
t.push_back("1");
t.push_back("2");
string name("2");
vector<toto>::iterator it = remove_if(t.begin(), t.end(),
bind2nd(mem_fun_ref(&toto::test), name)); // <= error
t.erase(it, t.end());
return 0;
}
I found a workaround: creating a
bool testZ(const string& var) const { return testZ(var); }
But I can't seem to find the correct template parameters, if that's even possible, to give to mem_fun_ref (or bind2nd?) to make it compile without my workaround.
Is there anyway to achieve this without my workaround, or is the workaround the "preferred" method?
You should be able to cast it according to C++ overloaded method pointer:
bind2nd(mem_fun_ref((bool (toto::*)(const string&) const) &toto::test), name));
I'm trying to implement the hash table class, but when I try to access the STL list member functions and iterator in the Hash_Table class, visual studio says no members available. Here is my code:
#include <iostream>
#include <vector>
#include <string>
#include <list>
#define INIT_SIZE 11
using namespace std;
template<typename KEY_TYPE, typename VALUE_TYPE>
class Hash_Table
{
public:
typedef pair<const KEY_TYPE, VALUE_TYPE> Entry_Type;
// Constructor
Hash_Table(const int size = INIT_SIZE)
{
myTable.resize(size);
}
// HashCode() function for calculating hash code of a specified key;
int HashCode(const KEY_TYPE& key)
{
int index = hash<KEY_TYPE>(key) % myTable.size();
return index;
}
void Insert (const Entry_Type& value)
{
}
// Index operator
Entry_Type& operator [] (const KEY_TYPE& key)
{
typename list<Entry_Type>:: ;//no members available
myTable[0]. ; //no members available
}
void Rehash ();
private:
// the table
vector<list<Entry_Type>> myTable;
};
Can anyone tell me why it happens? Thank you so much!
I am having issues with the following snippet of code
string const& symbol::at(int index) const {
assert(index<symbol_data.vector::size());
return symbol_data.vector::at(index);
}
Here, symbol_data is a private member of the class and is a vector
::at is a member function in the symbol class that I have defined.
When I try compiling this code, I get the following error messsage:
error: ‘template<class _Tp, class _Alloc> class std::vector’ used without template parameters
However, there is no error if I change the function prototype to
string symbol::at(int index) {...}
Does anybody know how I can get STL vectors to work properly with const references?
Your code as I'm writing this:
string const& symbol::at(int index) const {
assert(index<symbol_data.vector::size());
return symbol_data.vector::at(index);
}
Instead of symbol_data.vector:: write just symbol_data..
Cheers & hth.,
I can't reproduce your problem; the following compiles and works fine on VS2010 express.
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
class symbol
{
std::vector<std::string> symbol_data;
public:
symbol()
{
symbol_data.push_back( "Str1" );
symbol_data.push_back( "Str2" );
}
std::string const& at( int index ) const
{
assert( index < symbol_data.vector::size() );
return symbol_data.vector::at( index );
}
};
int main()
{
symbol s;
std::cout << s.at( 0 ) << std::endl;
std::cin.get();
return 0;
}