Related
I keep on getting issues when i try to compile this code. I think the origin of the problem is the declaration of the iterator in the set and so the erase operations are giving problems as a consequence.
The compilation error is the following:
the compiler gives this message:
Treecode.cc: In member function ‘void Treecode::recalcular_treecode()’:
Treecode.cc:35:24: error: no match for ‘operator=’ (operand types are ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >::const_iterator {aka __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > > >}’ and ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena>::iterator {aka __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >}’)
it = cjt_arb.begin();
^
In file included from /usr/include/c++/7/debug/set.h:34:0,
from /usr/include/c++/7/debug/set:35,
from /usr/include/c++/7/set:66,
from Treecode.hh:10,
from Treecode.cc:1:
/usr/include/c++/7/debug/safe_iterator.h:199:7: note: candidate: __gnu_debug::_Safe_iterator<_Iterator, _Sequence>& __gnu_debug::_Safe_iterator<_Iterator, _Sequence>::operator=(const __gnu_debug::_Safe_iterator<_Iterator, _Sequence>&) [with _Iterator = std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; _Sequence = std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >]
operator=(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
^~~~~~~~
/usr/include/c++/7/debug/safe_iterator.h:199:7: note: no known conversion for argument 1 from ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena>::iterator {aka __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >}’ to ‘const __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > > >&’
/usr/include/c++/7/debug/safe_iterator.h:231:7: note: candidate: __gnu_debug::_Safe_iterator<_Iterator, _Sequence>& __gnu_debug::_Safe_iterator<_Iterator, _Sequence>::operator=(__gnu_debug::_Safe_iterator<_Iterator, _Sequence>&&) [with _Iterator = std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; _Sequence = std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >]
operator=(_Safe_iterator&& __x) noexcept
^~~~~~~~
/usr/include/c++/7/debug/safe_iterator.h:231:7: note: no known conversion for argument 1 from ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena>::iterator {aka __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >}’ to ‘__gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > > >&&’
Treecode.cc:42:30: error: no matching function for call to ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena>::erase(std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >::const_iterator&)’
it = cjt_arb.erase(it);
^
In file included from /usr/include/c++/7/debug/set:35:0,
from /usr/include/c++/7/set:66,
from Treecode.hh:10,
from Treecode.cc:1:
/usr/include/c++/7/debug/set.h:346:7: note: candidate: std::__debug::set<_Key, _Compare, _Allocator>::iterator std::__debug::set<_Key, _Compare, _Allocator>::erase(std::__debug::set<_Key, _Compare, _Allocator>::const_iterator) [with _Key = BinTree<std::pair<std::__cxx11::basic_string<char>, int> >; _Compare = Treecode::ordena; _Allocator = std::allocator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; std::__debug::set<_Key, _Compare, _Allocator>::iterator = __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >; typename std::__cxx1998::set<_Key, _Compare, _Alloc>::iterator = std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; std::__debug::set<_Key, _Compare, _Allocator>::const_iterator = __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >; typename std::__cxx1998::set<_Key, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >]
erase(const_iterator __position)
^~~~~
/usr/include/c++/7/debug/set.h:346:7: note: no known conversion for argument 1 from ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >::const_iterator {aka __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > > >}’ to ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena>::const_iterator {aka __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >}’
/usr/include/c++/7/debug/set.h:363:7: note: candidate: std::__debug::set<_Key, _Compare, _Allocator>::size_type std::__debug::set<_Key, _Compare, _Allocator>::erase(const key_type&) [with _Key = BinTree<std::pair<std::__cxx11::basic_string<char>, int> >; _Compare = Treecode::ordena; _Allocator = std::allocator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; std::__debug::set<_Key, _Compare, _Allocator>::size_type = long unsigned int; std::__debug::set<_Key, _Compare, _Allocator>::key_type = BinTree<std::pair<std::__cxx11::basic_string<char>, int> >]
erase(const key_type& __x)
^~~~~
/usr/include/c++/7/debug/set.h:363:7: note: no known conversion for argument 1 from ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >::const_iterator {aka __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > > >}’ to ‘const key_type& {aka const BinTree<std::pair<std::__cxx11::basic_string<char>, int> >&}’
/usr/include/c++/7/debug/set.h:378:7: note: candidate: std::__debug::set<_Key, _Compare, _Allocator>::iterator std::__debug::set<_Key, _Compare, _Allocator>::erase(std::__debug::set<_Key, _Compare, _Allocator>::const_iterator, std::__debug::set<_Key, _Compare, _Allocator>::const_iterator) [with _Key = BinTree<std::pair<std::__cxx11::basic_string<char>, int> >; _Compare = Treecode::ordena; _Allocator = std::allocator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; std::__debug::set<_Key, _Compare, _Allocator>::iterator = __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >; typename std::__cxx1998::set<_Key, _Compare, _Alloc>::iterator = std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; std::__debug::set<_Key, _Compare, _Allocator>::const_iterator = __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >; typename std::__cxx1998::set<_Key, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >]
erase(const_iterator __first, const_iterator __last)
^~~~~
/usr/include/c++/7/debug/set.h:378:7: note: candidate expects 2 arguments, 1 provided
Treecode.cc:45:30: error: no matching function for call to ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena>::erase(std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >::const_iterator&)’
it = cjt_arb.erase(it);
^
In file included from /usr/include/c++/7/debug/set:35:0,
from /usr/include/c++/7/set:66,
from Treecode.hh:10,
from Treecode.cc:1:
/usr/include/c++/7/debug/set.h:346:7: note: candidate: std::__debug::set<_Key, _Compare, _Allocator>::iterator std::__debug::set<_Key, _Compare, _Allocator>::erase(std::__debug::set<_Key, _Compare, _Allocator>::const_iterator) [with _Key = BinTree<std::pair<std::__cxx11::basic_string<char>, int> >; _Compare = Treecode::ordena; _Allocator = std::allocator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; std::__debug::set<_Key, _Compare, _Allocator>::iterator = __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >; typename std::__cxx1998::set<_Key, _Compare, _Alloc>::iterator = std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; std::__debug::set<_Key, _Compare, _Allocator>::const_iterator = __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >; typename std::__cxx1998::set<_Key, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >]
erase(const_iterator __position)
^~~~~
/usr/include/c++/7/debug/set.h:346:7: note: no known conversion for argument 1 from ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >::const_iterator {aka __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > > >}’ to ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena>::const_iterator {aka __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >}’
/usr/include/c++/7/debug/set.h:363:7: note: candidate: std::__debug::set<_Key, _Compare, _Allocator>::size_type std::__debug::set<_Key, _Compare, _Allocator>::erase(const key_type&) [with _Key = BinTree<std::pair<std::__cxx11::basic_string<char>, int> >; _Compare = Treecode::ordena; _Allocator = std::allocator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; std::__debug::set<_Key, _Compare, _Allocator>::size_type = long unsigned int; std::__debug::set<_Key, _Compare, _Allocator>::key_type = BinTree<std::pair<std::__cxx11::basic_string<char>, int> >]
erase(const key_type& __x)
^~~~~
/usr/include/c++/7/debug/set.h:363:7: note: no known conversion for argument 1 from ‘std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >::const_iterator {aka __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > > >}’ to ‘const key_type& {aka const BinTree<std::pair<std::__cxx11::basic_string<char>, int> >&}’
/usr/include/c++/7/debug/set.h:378:7: note: candidate: std::__debug::set<_Key, _Compare, _Allocator>::iterator std::__debug::set<_Key, _Compare, _Allocator>::erase(std::__debug::set<_Key, _Compare, _Allocator>::const_iterator, std::__debug::set<_Key, _Compare, _Allocator>::const_iterator) [with _Key = BinTree<std::pair<std::__cxx11::basic_string<char>, int> >; _Compare = Treecode::ordena; _Allocator = std::allocator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; std::__debug::set<_Key, _Compare, _Allocator>::iterator = __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >; typename std::__cxx1998::set<_Key, _Compare, _Alloc>::iterator = std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >; std::__debug::set<_Key, _Compare, _Allocator>::const_iterator = __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >, std::__debug::set<BinTree<std::pair<std::__cxx11::basic_string<char>, int> >, Treecode::ordena> >; typename std::__cxx1998::set<_Key, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<BinTree<std::pair<std::__cxx11::basic_string<char>, int> > >]
erase(const_iterator __first, const_iterator __last)
^~~~~
/usr/include/c++/7/debug/set.h:378:7: note: candidate expects 2 arguments, 1 provided
I've tried dereferencing the declaration doing it = cjt_arb.begin() in the next line but it doesn't work.
#include "Treecode.hh"
using namespace std;
void Treecode::recalcular_treecode() {
set<BinTree<pair<string,int>>>::iterator it = cjt_arb.begin(); // Problem probably here
if (cjt_arb.size() == 1) {tree = *it;}
else {
pair <string, int> a;
pair <string, int> b;
BinTree <pair <string,int> > left = *it;
a = left.value();
it = cjt_arb.erase(it);
BinTree <pair <string,int> > right = *it;
b = right.value();
it = cjt_arb.erase(it);
pair <string, int> node;
if (a.first <b.first) {node.first = a.first + b.first;}
else {node.first = b.first + a.first;}
node.second = a.second + b.second;
BinTree<pair<string,int>> unio(node,left, right);
cjt_arb.insert(unio);
recalcular_treecode();
}
}
As you have already figured out, the compiler is complaining about it = cjt_arb.begin(); not compiling. It tries to tell you why:
error: no match for ‘operator=’ (operand types are ‘std::__debug::set, int> > >::const_iterator {aka __gnu_debug::_Safe_iterator, int> > >, std::__debug::set, int> > > >}’ and ‘std::__debug::set, int> >, Treecode::ordena>::iterator {aka __gnu_debug::_Safe_iterator, int> > >, std::__debug::set, int> >, Treecode::ordena> >}’)
it = cjt_arb.begin();
What it is trying to say is
Error: No valid operator= to assign a set<BinTree<pair<string,int>>>::const_iterator to a set<BinTree<pair<string,int>>>::iterator because that would drop the constness.
Your cjt_arb seems to be const, so you can't modify it, so you cannot get a non-const iterator to it. Replace set<BinTree<pair<string,int>>>::iterator with set<BinTree<pair<string,int>>>::const_iterator or remove the const from cjt_arb and it should compile.
I have solved the problem of getting this code to compile by removing the "const". However, why does it seem I cannot assign non-class members in a const class method in this specific situation? It probably is part of the class; though, I do not understand why.
I got my code to compile, but I am confused at this situation.
Below, are some declarations in the class.
using twoDList = multimap<string,string>;
twoDList SomeMultiMap;
This will work when I take off the "const". Or at least compile. Though, here I am just assigning iterators declared only in this function. Using namespace std by the way.
bool object::foo(string a, string b) const
{
pair<object::twoDList::iterator,object::twoDList::iterator> wordRange;
wordRange = SomeMultiMap.equal_range(a);
object::twoDList::iterator it = wordRange.first;
//...
//...
//...
}
I expected this function to compile without removing the const, but it does not compile.
Edit: here are the compilation errors, and I am using this on linux command line.
g++ -g -DDEBUG -std=c++11 -c test1.cpp
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:64:0,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from test1.cpp:1:
/usr/include/c++/4.8/bits/stl_pair.h: In instantiation of ‘std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(std::pair<_U1, _U2>&&) [with _U1 = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >; _U2 = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >; _T1 = std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >; _T2 = std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >]’:
test1.cpp:15:15: required from here
/usr/include/c++/4.8/bits/stl_pair.h:188:10: error: no match for ‘operator=’ (operand types are ‘std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ and ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’)
first = std::forward<_U1>(__p.first);
^
/usr/include/c++/4.8/bits/stl_pair.h:188:10: note: candidates are:
In file included from /usr/include/c++/4.8/map:60:0,
from test1.cpp:2:
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >& std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >::operator=(const std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&)
struct _Rb_tree_iterator
^
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: no known conversion for argument 1 from ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ to ‘const std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&’
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >& std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >::operator=(std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&&)
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: no known conversion for argument 1 from ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ to ‘std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&&’
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:64:0,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from test1.cpp:1:
/usr/include/c++/4.8/bits/stl_pair.h:189:11: error: no match for ‘operator=’ (operand types are ‘std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ and ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’)
second = std::forward<_U2>(__p.second);
^
/usr/include/c++/4.8/bits/stl_pair.h:189:11: note: candidates are:
In file included from /usr/include/c++/4.8/map:60:0,
from test1.cpp:2:
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >& std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >::operator=(const std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&)
struct _Rb_tree_iterator
^
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: no known conversion for argument 1 from ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ to ‘const std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&’
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >& std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >::operator=(std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&&)
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: no known conversion for argument 1 from ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ to ‘std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&&’
makefile:10: recipe for target 'test1.o' failed
make: *** [test1.o] Error 1
Edit: more edits to fix scope operators. Also, added the fact that I am using namespace std if that helps.
A const after a member function's parameter list is a promise not to change the class object via the this pointer. The type of this becomes const ClassType* instead of just ClassType*. (Like any pointer-to-const or reference-to-const, this only means the thing can't be changed using that pointer or reference, not that the object is permanently const or can't be changed by other means.)
To say a class object is treated as const means that all its members (except any marked mutable) are treated as const. And since in a member function definition a plain non-static member name N actually means the same as this->N, members named that way are treated as const when the function declaration has a const after the parameter list.
So inside bool object::foo(string a, string b) const, the name SomeMultiMap, being a member of object, is treated as a const SomeMultiMap. And equal_range gives a pair<const_iterator, const_iterator> when the multimap object expression is const, or a pair<iterator, iterator> only when the object expression is not const.
So this may work instead (depending on what you need to do afterward):
std::pair<twoDList::const_iterator,twoDList::const_iterator> wordRange;
wordRange = SomeMultiMap.equal_range(a);
twoDList::const_iterator it = wordRange.first;
(Note you usually don't need the object:: prefixes, since the member function body is in its class's scope.)
Although I would just define these variables with auto instead, avoiding the need to get the type exactly right, and saving on typing out those long iterator names.
auto wordRange = SomeMultiMap.equal_range(a);
auto it = wordRange.first;
I would like to create a simple map like this:
std::map<const std::string, const std::string> mymap;
mymap.insert("foo", "bar");
when I try this, I get this error:
In file included from /usr/include/c++/4.8.2/map:60:0,
from /home/me/dev/some-project/blocks/mycompany/some-project/main.cpp:11:
/usr/include/c++/4.8.2/bits/stl_tree.h: In instantiation of ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique_(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Arg&&) [with _Arg = const char&; _Key = const std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, const std::basic_string<char> >; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, const std::basic_string<char> > >; _Compare = std::less<const std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, const std::basic_string<char> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, const std::basic_string<char> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, const std::basic_string<char> > >]’:
/usr/include/c++/4.8.2/bits/stl_tree.h:1722:37: required from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_II, _II) [with _InputIterator = const char*; _Key = const std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, const std::basic_string<char> >; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, const std::basic_string<char> > >; _Compare = std::less<const std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, const std::basic_string<char> > >]’
/usr/include/c++/4.8.2/bits/stl_map.h:671:11: required from ‘void std::map<_Key, _Tp, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _InputIterator = const char*; _Key = const std::basic_string<char>; _Tp = const std::basic_string<char>; _Compare = std::less<const std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, const std::basic_string<char> > >]’
/home/me/dev/some-project/blocks/mycompany/some-project/main.cpp:38:57: required from here
/usr/include/c++/4.8.2/bits/stl_tree.h:1478:63: error: no match for call to ‘(std::_Select1st<std::pair<const std::basic_string<char>, const std::basic_string<char> > >) (const char&)’
= _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v));
^
In file included from /usr/include/c++/4.8.2/string:48:0,
from /usr/include/c++/4.8.2/bits/locale_classes.h:40,
from /usr/include/c++/4.8.2/bits/ios_base.h:41,
from /usr/include/c++/4.8.2/ios:42,
from /usr/include/c++/4.8.2/ostream:38,
from /usr/include/c++/4.8.2/iostream:39,
from /home/me/dev/some-project/blocks/mycompany/some-project/main.cpp:10:
/usr/include/c++/4.8.2/bits/stl_function.h:486:12: note: candidates are:
struct _Select1st
^...
It goes on and on, but I cannot tell what the problem is from the error output.
I cannot paste the rest of it because stackoverflow says I have too much code and not enough text.
That's simply not how you use std::map<..>::insert in C++. You should insert a std::pair<std::string,std::string>(std::string("a"), std::string("b")). See your arbitrary C++ reference.
You might get away without using std::string("a"), because there's a std::string constructor that takes C strings.
You're using insert() when you should be using emplace() or operator[].
However, you can't use const std::string when using operator[].
std::map<std::string, std::string> mymap;
mymap["foo"] = "bar";
If you're really bent on using insert() and const std::string, you have to insert an std::pair<const std::string, const std::string>.
std::map<const std::string, const std::string> mymap;
std::pair<const std::string,const std::string> p("foo", "bar");
mymap.insert(p);
Then there's the C++11 way, using an initializer list:
std::map<const std::string, const std::string> mymap;
mymap.insert({ "foo", "bar" });
You can insert std::pair into a map using insert.
mymap.insert(std::pair<const std::string, const std::string>("a", "b"));
This question already has an answer here:
Spirit Qi attribute propagation issue with single-member struct
(1 answer)
Closed 8 years ago.
#include <iostream>
#include <vector>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
namespace qi = boost::spirit::qi;
struct VectorWrapper
{
std::vector<std::string> data;
};
BOOST_FUSION_ADAPT_STRUCT(
VectorWrapper,
(std::vector<std::string>, data)
)
int main ()
{
std::string input("aa aa aa");
std::string::iterator strbegin = input.begin();
qi::rule<std::string::iterator, VectorWrapper(), qi::space_type > testRule =
+(qi::string("aa"));
VectorWrapper result;
bool ok = qi::phrase_parse(
strbegin,
input.end(),
testRule,
qi::space,
result);
if (ok && strbegin == input.end()) {
std::cout << result.data.size();
for (int i = 0; i < result.data.size(); ++i) {
std::cout << result.data[i] << " ";
}
} else {
std::cout << "fail" << std::endl;
std::cout << std::string(strbegin, input.end()) << std::endl;
}
}
I need help to find out problem in this code. Compiler complains about type in VectorWrapper struct but shouldn't BOOST_FUSION_ADAPT_STRUCT add it?
After adding dummy field (from this answer)I am getting the same error:
struct VectorWrapper
{
std::vector<std::string> data;
qi::unused_type dummy;
};
BOOST_FUSION_ADAPT_STRUCT(
VectorWrapper,
(std::vector<std::string>, data)
(qi::unused_type, dummy)
)
The error message:
In file included from /usr/local/include/boost/spirit/home/support/string_traits.hpp:16:0,
from /usr/local/include/boost/spirit/home/support/nonterminal/expand_arg.hpp:20,
from /usr/local/include/boost/spirit/home/support/context.hpp:18,
from /usr/local/include/boost/spirit/home/qi/domain.hpp:18,
from /usr/local/include/boost/spirit/home/qi/meta_compiler.hpp:15,
from /usr/local/include/boost/spirit/home/qi/action/action.hpp:14,
from /usr/local/include/boost/spirit/home/qi/action.hpp:14,
from /usr/local/include/boost/spirit/home/qi.hpp:14,
from /usr/local/include/boost/spirit/include/qi.hpp:16,
from main.cpp:4:
/usr/local/include/boost/spirit/home/support/container.hpp: In instantiation of ‘boost::spirit::traits::container_value<VectorWrapper, void>’:
/usr/local/include/boost/spirit/home/qi/detail/pass_container.hpp:296:66: instantiated from ‘bool boost::spirit::qi::detail::pass_container<F, Attr, Sequence>::dispatch_attribute(const Component&, mpl_::true_) const [with Component = boost::spirit::qi::literal_string<const char (&)[3], false>, F = boost::spirit::qi::detail::fail_function<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >, boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> > >, Attr = VectorWrapper, Sequence = mpl_::bool_<false>, mpl_::true_ = mpl_::bool_<true>]’
/usr/local/include/boost/spirit/home/qi/detail/pass_container.hpp:331:61: instantiated from ‘bool boost::spirit::qi::detail::pass_container<F, Attr, Sequence>::operator()(const Component&) const [with Component = boost::spirit::qi::literal_string<const char (&)[3], false>, F = boost::spirit::qi::detail::fail_function<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >, boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> > >, Attr = VectorWrapper, Sequence = mpl_::bool_<false>]’
/usr/local/include/boost/spirit/home/qi/operator/plus.hpp:63:13: instantiated from ‘bool boost::spirit::qi::plus<Subject>::parse_container(F) const [with F = boost::spirit::qi::detail::pass_container<boost::spirit::qi::detail::fail_function<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >, boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> > >, VectorWrapper, mpl_::bool_<false> >, Subject = boost::spirit::qi::literal_string<const char (&)[3], false>]’
/usr/local/include/boost/spirit/home/qi/operator/plus.hpp:85:13: instantiated from ‘bool boost::spirit::qi::plus<Subject>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, Context = boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, Attribute = VectorWrapper, Subject = boost::spirit::qi::literal_string<const char (&)[3], false>]’
/usr/local/include/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:43:54: instantiated from ‘bool boost::spirit::qi::detail::parser_binder<Parser, Auto>::call(Iterator&, const Iterator&, Context&, const Skipper&, mpl_::false_) const [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, Context = boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >, Parser = boost::spirit::qi::plus<boost::spirit::qi::literal_string<const char (&)[3], false> >, Auto = mpl_::bool_<false>, mpl_::false_ = mpl_::bool_<false>]’
/usr/local/include/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:53:67: [ skipping 3 instantiation contexts ]
/usr/local/include/boost/function/function_template.hpp:722:7: instantiated from ‘boost::function4<R, T1, T2, T3, T4>::function4(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::plus<boost::spirit::qi::literal_string<const char (&)[3], false> >, mpl_::bool_<false> >, R = bool, T0 = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T1 = const __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T2 = boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >&, T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >&, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/usr/local/include/boost/function/function_template.hpp:1069:16: instantiated from ‘boost::function<R(T0, T1, T2, T3)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::plus<boost::spirit::qi::literal_string<const char (&)[3], false> >, mpl_::bool_<false> >, R = bool, T0 = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T1 = const __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T2 = boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >&, T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >&, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/usr/local/include/boost/function/function_template.hpp:1124:5: instantiated from ‘typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, boost::function<R(T0, T1, T2, T3)>&>::type boost::function<R(T0, T1, T2, T3)>::operator=(Functor) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::plus<boost::spirit::qi::literal_string<const char (&)[3], false> >, mpl_::bool_<false> >, R = bool, T0 = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T1 = const __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T2 = boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >&, T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >&, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, boost::function<R(T0, T1, T2, T3)>&>::type = boost::function<bool(__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, const __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >&, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >&)>&]’
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:182:13: instantiated from ‘static void boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&, mpl_::true_) [with Auto = mpl_::bool_<false>, Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::unary_plus, boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::terminal_ex<boost::spirit::tag::char_code<boost::spirit::tag::string, boost::spirit::char_encoding::standard>, boost::fusion::vector1<const char (&)[3]> > >, 0l>&>, 1l>, Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, T1 = VectorWrapper(), T2 = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0l>, T3 = boost::spirit::unused_type, T4 = boost::spirit::unused_type, boost::spirit::qi::rule<Iterator, T1, T2, T3, T4> = boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, VectorWrapper(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0l> >, mpl_::true_ = mpl_::bool_<true>]’
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:191:13: instantiated from ‘boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::rule(const Expr&, const string&) [with Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::unary_plus, boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::terminal_ex<boost::spirit::tag::char_code<boost::spirit::tag::string, boost::spirit::char_encoding::standard>, boost::fusion::vector1<const char (&)[3]> > >, 0l>&>, 1l>, Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, T1 = VectorWrapper(), T2 = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0l>, T3 = boost::spirit::unused_type, T4 = boost::spirit::unused_type, std::string = std::basic_string<char>]’
main.cpp:27:27: instantiated from here
/usr/local/include/boost/spirit/home/support/container.hpp:116:12: error: no type named ‘value_type’ in ‘struct VectorWrapper’
In file included from /usr/local/include/boost/spirit/home/qi/operator/kleene.hpp:20:0,
from /usr/local/include/boost/spirit/home/qi/directive/repeat.hpp:18,
from /usr/local/include/boost/spirit/home/qi/directive.hpp:23,
from /usr/local/include/boost/spirit/home/qi.hpp:19,
from /usr/local/include/boost/spirit/include/qi.hpp:16,
from main.cpp:4:
/usr/local/include/boost/spirit/home/qi/detail/pass_container.hpp: In member function ‘bool boost::spirit::qi::detail::pass_container<F, Attr, Sequence>::dispatch_attribute(const Component&, mpl_::true_) const [with Component = boost::spirit::qi::literal_string<const char (&)[3], false>, F = boost::spirit::qi::detail::fail_function<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >, boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> > >, Attr = VectorWrapper, Sequence = mpl_::bool_<false>, mpl_::true_ = mpl_::bool_<true>]’:
/usr/local/include/boost/spirit/home/qi/detail/pass_container.hpp:331:61: instantiated from ‘bool boost::spirit::qi::detail::pass_container<F, Attr, Sequence>::operator()(const Component&) const [with Component = boost::spirit::qi::literal_string<const char (&)[3], false>, F = boost::spirit::qi::detail::fail_function<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >, boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> > >, Attr = VectorWrapper, Sequence = mpl_::bool_<false>]’
/usr/local/include/boost/spirit/home/qi/operator/plus.hpp:63:13: instantiated from ‘bool boost::spirit::qi::plus<Subject>::parse_container(F) const [with F = boost::spirit::qi::detail::pass_container<boost::spirit::qi::detail::fail_function<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >, boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> > >, VectorWrapper, mpl_::bool_<false> >, Subject = boost::spirit::qi::literal_string<const char (&)[3], false>]’
/usr/local/include/boost/spirit/home/qi/operator/plus.hpp:85:13: instantiated from ‘bool boost::spirit::qi::plus<Subject>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, Context = boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, Attribute = VectorWrapper, Subject = boost::spirit::qi::literal_string<const char (&)[3], false>]’
/usr/local/include/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:43:54: instantiated from ‘bool boost::spirit::qi::detail::parser_binder<Parser, Auto>::call(Iterator&, const Iterator&, Context&, const Skipper&, mpl_::false_) const [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, Context = boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >, Parser = boost::spirit::qi::plus<boost::spirit::qi::literal_string<const char (&)[3], false> >, Auto = mpl_::bool_<false>, mpl_::false_ = mpl_::bool_<false>]’
/usr/local/include/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:53:67: instantiated from ‘bool boost::spirit::qi::detail::parser_binder<Parser, Auto>::operator()(Iterator&, const Iterator&, Context&, const Skipper&) const [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, Context = boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >, Parser = boost::spirit::qi::plus<boost::spirit::qi::literal_string<const char (&)[3], false> >, Auto = mpl_::bool_<false>]’
/usr/local/include/boost/function/function_template.hpp:132:42: [ skipping 2 instantiation contexts ]
/usr/local/include/boost/function/function_template.hpp:722:7: instantiated from ‘boost::function4<R, T1, T2, T3, T4>::function4(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::plus<boost::spirit::qi::literal_string<const char (&)[3], false> >, mpl_::bool_<false> >, R = bool, T0 = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T1 = const __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T2 = boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >&, T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >&, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/usr/local/include/boost/function/function_template.hpp:1069:16: instantiated from ‘boost::function<R(T0, T1, T2, T3)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::plus<boost::spirit::qi::literal_string<const char (&)[3], false> >, mpl_::bool_<false> >, R = bool, T0 = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T1 = const __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T2 = boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >&, T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >&, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/usr/local/include/boost/function/function_template.hpp:1124:5: instantiated from ‘typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, boost::function<R(T0, T1, T2, T3)>&>::type boost::function<R(T0, T1, T2, T3)>::operator=(Functor) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::plus<boost::spirit::qi::literal_string<const char (&)[3], false> >, mpl_::bool_<false> >, R = bool, T0 = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T1 = const __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, T2 = boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >&, T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >&, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, boost::function<R(T0, T1, T2, T3)>&>::type = boost::function<bool(__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, const __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&, boost::spirit::context<boost::fusion::cons<VectorWrapper&, boost::fusion::nil>, boost::fusion::vector0<> >&, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >&)>&]’
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:182:13: instantiated from ‘static void boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&, mpl_::true_) [with Auto = mpl_::bool_<false>, Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::unary_plus, boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::terminal_ex<boost::spirit::tag::char_code<boost::spirit::tag::string, boost::spirit::char_encoding::standard>, boost::fusion::vector1<const char (&)[3]> > >, 0l>&>, 1l>, Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, T1 = VectorWrapper(), T2 = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0l>, T3 = boost::spirit::unused_type, T4 = boost::spirit::unused_type, boost::spirit::qi::rule<Iterator, T1, T2, T3, T4> = boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, VectorWrapper(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0l> >, mpl_::true_ = mpl_::bool_<true>]’
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:191:13: instantiated from ‘boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::rule(const Expr&, const string&) [with Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::unary_plus, boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::terminal_ex<boost::spirit::tag::char_code<boost::spirit::tag::string, boost::spirit::char_encoding::standard>, boost::fusion::vector1<const char (&)[3]> > >, 0l>&>, 1l>, Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, T1 = VectorWrapper(), T2 = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0l>, T3 = boost::spirit::unused_type, T4 = boost::spirit::unused_type, std::string = std::basic_string<char>]’
main.cpp:27:27: instantiated from here
/usr/local/include/boost/spirit/home/qi/detail/pass_container.hpp:296:66: error: no type named ‘type’ in ‘struct boost::spirit::traits::container_value<VectorWrapper, void>’
/usr/local/include/boost/spirit/home/qi/detail/pass_container.hpp:309:15: error: no type named ‘type’ in ‘struct boost::spirit::traits::container_value<VectorWrapper, void>’
make: *** [all] Error 1
You need to emit an unused type in your rule:
qi::rule<std::string::iterator, VectorWrapper(), qi::space_type > testRule =
+(qi::string("aa")) >> qi::attr(false);
The linked answer should be enough. Since you report trouble still: here's something that works on my compilers:
qi::rule<std::string::iterator, VectorWrapper(), qi::space_type > testRule =
qi::eps >> +(qi::string("aa"));
See it Live On Coliru
I'm clearly missing something here, but what?
Definition (... denotes valid code, not actual three points):
class CrmxFile {
private:
const std::vector<std::string> validValues;
int value;
public:
void setValue(std::string _value);
...
}
std::vector<std::string> CrmxFile = {...};
In the code I have this:
void Crmx::SetValue(std::string _value) {
std::vector<std::string>::iterator idx;
if((idx = std::find(validValues.begin(), validValues.end(), _value)) == validValues.end()) {
value = 0;
}
else {
value = idx - validValues.begin();
}
}
I compile this with gcc -c -std=c++0x and I get this error:
CrmxFile.cpp: In member function ‘void CrmxFile::SetValue(std::string)’:
CrmxFile.cpp:24:64: error: no match for ‘operator=’ in ‘idx = std::find [with _IIter = __gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >, _Tp = std::basic_string<char>](Id3V1::validValues.std::vector<_Tp, _Alloc>::begin [with _Tp = std::basic_string<char>, _Alloc = std::allocator<std::basic_string<char> >, std::vector<_Tp, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::const_pointer = const std::basic_string<char>*](), Id3V1::validValues.std::vector<_Tp, _Alloc>::end [with _Tp = std::basic_string<char>, _Alloc = std::allocator<std::basic_string<char> >, std::vector<_Tp, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::const_pointer = const std::basic_string<char>*](), (*(const std::basic_string<char>*)(& _value)))’
CrmxFile.cpp:24:64: note: candidates are:
/usr/include/c++/4.6/bits/stl_iterator.h:702:11: note: __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >& __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >::operator=(const __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >&)
/usr/include/c++/4.6/bits/stl_iterator.h:702:11: note: no known conversion for argument 1 from ‘__gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >’ to ‘const __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >&’
/usr/include/c++/4.6/bits/stl_iterator.h:702:11: note: __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >& __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >::operator=(__gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >&&)
/usr/include/c++/4.6/bits/stl_iterator.h:702:11: note: no known conversion for argument 1 from ‘__gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >’ to ‘__gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >&&’
What am I missing? Or, alternatively, is there a better way of finding the index of a given value in a vector?
idx has to be a const_iterator since validValues is a const vector<...>.
std::vector<std::string>::const_iterator idx;
Since validValues is const, begin(), end(), and therefore this instantiation of std::find, all return std::vector<std::string>::const_iterator, not std::vector<std::string>::iterator. For const-safety, a const_iterator cannot convert to an iterator.
validValues is defined as const std::vector<std::string>. Therefore begin() and end() will return const_iterator, but you are trying to assign the result to a iterator. Converting a const_iterator to an iterator would break const correctness (since you could then go on and change the underlying object) and is therefore not allowed.
Change the definition of idx to be std::vector<std::string>::const_iterator and it should work.
"What am I missing?"
Is yours first validValues invalid?
I suggest:
void Crmx::SetValue(std::string _value) {
value = std::find(validValues.begin(), validValues.end(), _value) - validValues.begin();
}
and use the validValues.size as invalid value, not 0