weird error

J

Joe Laughlin

(file and class names changed to protect the innocent)

g++ -Wall -c file.cpp: In member function `std::string
Some_Class::get_member(const std::string&) const':
file.cpp:46: passing `const std::map<std::string,
std::string, std::less<std::string>, std::allocator<std::pair<const
std::string, std::string> > >' as `this' argument of `_Tp& std::map<_Key,
_Tp, _Compare, _Alloc>::eek:perator[](const _Key&) [with _Key = std::string,
_Tp = std::string, _Compare = std::less<std::string>, _Alloc =
std::allocator<std::pair<const std::string, std::string> >]' discards
qualifiers

I can't make heads or tails of this error. I'm guessing it has something to
do with calling a non-const function on some const object. Any ideas?

The function SomeClass::get_member is:

std::string SomeClass::get_member(const std::string &name) const
{
return _member[name];
}

where _member is a std::map<std::string, std::string>.
 
V

Victor Bazarov

Joe Laughlin said:
(file and class names changed to protect the innocent)

g++ -Wall -c file.cpp: In member function `std::string
Some_Class::get_member(const std::string&) const':
file.cpp:46: passing `const std::map<std::string,
std::string, std::less<std::string>, std::allocator<std::pair<const
std::string, std::string> > >' as `this' argument of `_Tp&
std::map<_Key,
_Tp, _Compare, _Alloc>::eek:perator[](const _Key&) [with _Key =
std::string,
_Tp = std::string, _Compare = std::less<std::string>, _Alloc =
std::allocator<std::pair<const std::string, std::string> >]' discards
qualifiers

I can't make heads or tails of this error. I'm guessing it has something
to
do with calling a non-const function on some const object. Any ideas?

The function SomeClass::get_member is:

std::string SomeClass::get_member(const std::string &name) const
{
return _member[name];
}

where _member is a std::map<std::string, std::string>.

You declared this member function ('get_member') "const". That means that
the object (and all its data member except 'mutable' ones) are not going to
change. Indexing operator for 'map' template is a _non-const_ function.
I.e. it cannot be called for a const map. It has to be non-const because
it may insert a new object if it's not there yet.

You need to either make peace with the fact that it may insert another
object into your _member (and declare '_member' "mutable") or use some other
way. It seems that your function _assumes_ that there is an element with
the
key 'name' in the map. What if there isn't?

Victor
 
B

Brian Riis

Joe said:
(file and class names changed to protect the innocent)

g++ -Wall -c file.cpp: In member function `std::string
Some_Class::get_member(const std::string&) const':
file.cpp:46: passing `const std::map<std::string,
std::string, std::less<std::string>, std::allocator<std::pair<const
std::string, std::string> > >' as `this' argument of `_Tp& std::map<_Key,
_Tp, _Compare, _Alloc>::eek:perator[](const _Key&) [with _Key = std::string,
_Tp = std::string, _Compare = std::less<std::string>, _Alloc =
std::allocator<std::pair<const std::string, std::string> >]' discards
qualifiers

I can't make heads or tails of this error. I'm guessing it has something to
do with calling a non-const function on some const object. Any ideas?

The function SomeClass::get_member is:

std::string SomeClass::get_member(const std::string &name) const
{
return _member[name];

Your function is declared const, but you cannot guarantee that the
subscript operator of the map doesn't change the value at 'name'. In
other words: In a const member function you can only use other const
functions (in regard to your own members). In the above, if 'name' does
not exist in _member, *it will be created*. You are not allowed to do
that in a const function.

try this:

std::string SomeClass::get_member(std::string const & name) const
{
_member.const_iterator it;
it = _member.find(name);
if(it != _member.end())
_return it->second;
else
<...> // Whatever you want to do, if 'name' isn't there...
}

Takes up a bit more space, but it works. On most compilers I should
think it is as efficient too.
 
J

Joe Laughlin

Brian said:
Joe said:
(file and class names changed to protect the innocent)

g++ -Wall -c file.cpp: In member function `std::string
Some_Class::get_member(const std::string&) const':
file.cpp:46: passing `const std::map<std::string,
std::string, std::less<std::string>,
std::allocator<std::pair<const std::string,
std::string> > >' as `this' argument of `_Tp&
std::map<_Key, _Tp, _Compare,
_Alloc>::eek:perator[](const _Key&) [with _Key =
std::string, _Tp = std::string, _Compare =
_Alloc = said:
]' discards qualifiers

I can't make heads or tails of this error. I'm guessing
it has something to do with calling a non-const function
on some const object. Any ideas?

The function SomeClass::get_member is:

std::string SomeClass::get_member(const std::string
&name) const {
return _member[name];

Your function is declared const, but you cannot guarantee
that the subscript operator of the map doesn't change the
value at 'name'. In other words: In a const member
function you can only use other const functions (in
regard to your own members). In the above, if 'name' does
not exist in _member, *it will be created*. You are not
allowed to do that in a const function.

try this:

std::string SomeClass::get_member(std::string const &
name) const {
_member.const_iterator it;
it = _member.find(name);
if(it != _member.end())
_return it->second;
else
<...> // Whatever you want to do, if 'name' isn't
there... }

Takes up a bit more space, but it works. On most
compilers I should think it is as efficient too.

Thanks you guys.

Is:
_member.const_iterator it;
legal? The compiler didn't like that line, but it did like:
std::map<std::string, std::string>::const_iterator it;

Joe
 
J

John Harrison

Thanks you guys.

Is:
_member.const_iterator it;
legal?
No

The compiler didn't like that line, but it did like:
std::map<std::string, std::string>::const_iterator it;

I'm sure that's what Brian meant to say.

john
 
J

Joe Laughlin

Joe said:
(file and class names changed to protect the innocent)

g++ -Wall -c file.cpp: In member function `std::string
Some_Class::get_member(const std::string&) const':
file.cpp:46: passing `const std::map<std::string,
std::string, std::less<std::string>,
std::allocator<std::pair<const std::string,
std::string> > >' as `this' argument of `_Tp&
std::map<_Key, _Tp, _Compare,
_Alloc>::eek:perator[](const _Key&) [with _Key =
std::string, _Tp = std::string, _Compare =
_Alloc = said:
]' discards qualifiers

I can't make heads or tails of this error. I'm guessing
it has something to do with calling a non-const function
on some const object. Any ideas?

The function SomeClass::get_member is:

std::string SomeClass::get_member(const std::string
&name) const {
return _member[name];
}

where _member is a std::map<std::string, std::string>.

Here's another one, probably related to my lack of understanding about the
STL. (These error messages sure aren't very clear!)


Error is:
could not convert `
(&iter)->std::_List_iterator<_Tp, _Ref, _Ptr>::eek:perator*() const [with
_Tp =
SomeClass, _Ref = const SomeClass&, _Ptr = const
SomeClass*]()' to `SomeClass&'

SomeClass is a std::list of a user-defined class.

The error gets raised on the return statement of this function:
SomeClass& AnotherClass::get_element(const string& tag) const
{
std::list<SomeClass>::const_iterator iter = _elements.begin();

// This isn't very well written, and I'm sure there's better
// ways of doing it. Feel free to give me ideas on how to improve it.
while (iter != _elements.end())
{
if (iter->get_member("tag") == tag)
return *iter; // error rasied here
++iter;
}
// throw exception cuz not found
}
 
V

Victor Bazarov

Joe said:
Joe said:
(file and class names changed to protect the innocent)

g++ -Wall -c file.cpp: In member function `std::string
Some_Class::get_member(const std::string&) const':
file.cpp:46: passing `const std::map<std::string,
std::string, std::less<std::string>,
std::allocator<std::pair<const std::string,
std::string> > >' as `this' argument of `_Tp&
std::map<_Key, _Tp, _Compare,
_Alloc>::eek:perator[](const _Key&) [with _Key =
std::string, _Tp = std::string, _Compare =
_Alloc = said:
]' discards qualifiers

I can't make heads or tails of this error. I'm guessing
it has something to do with calling a non-const function
on some const object. Any ideas?

The function SomeClass::get_member is:

std::string SomeClass::get_member(const std::string
&name) const {
return _member[name];
}

where _member is a std::map<std::string, std::string>.


Here's another one, probably related to my lack of understanding about the
STL. (These error messages sure aren't very clear!)


Error is:
could not convert `
(&iter)->std::_List_iterator<_Tp, _Ref, _Ptr>::eek:perator*() const [with
_Tp =
SomeClass, _Ref = const SomeClass&, _Ptr = const
SomeClass*]()' to `SomeClass&'

SomeClass is a std::list of a user-defined class.

The error gets raised on the return statement of this function:
SomeClass& AnotherClass::get_element(const string& tag) const
{
std::list<SomeClass>::const_iterator iter = _elements.begin();

// This isn't very well written, and I'm sure there's better
// ways of doing it. Feel free to give me ideas on how to improve it.
while (iter != _elements.end())
{
if (iter->get_member("tag") == tag)
return *iter; // error rasied here
++iter;
}
// throw exception cuz not found
}

Your 'const' is all screwed up again. The return value of this function
is 'SomeClass&', a reference to non-const SomeClass object. The 'iter'
is declared as 'const_iterator', whose operator* (dereference operator)
yields a 'SomeClass const&', a reference to a const SomeClass object.
Of course it cannot convert a const ref to a non-const ref.

Victor
 
J

Joe Laughlin

Victor said:
Joe said:
Joe said:
(file and class names changed to protect the innocent)

g++ -Wall -c file.cpp: In member function `std::string
Some_Class::get_member(const std::string&) const':
file.cpp:46: passing `const std::map<std::string,
std::string, std::less<std::string>,
std::allocator<std::pair<const std::string,
std::string> > >' as `this' argument of `_Tp&
std::map<_Key, _Tp, _Compare,
_Alloc>::eek:perator[](const _Key&) [with _Key =
std::string, _Tp = std::string, _Compare =
std::less<std::string>, _Alloc =
std::allocator<std::pair<const std::string, std::string>

]' discards qualifiers

I can't make heads or tails of this error. I'm guessing
it has something to do with calling a non-const function
on some const object. Any ideas?

The function SomeClass::get_member is:

std::string SomeClass::get_member(const std::string
&name) const {
return _member[name];
}

where _member is a std::map<std::string, std::string>.


Here's another one, probably related to my lack of
understanding about the STL. (These error messages sure
aren't very clear!)


Error is:
could not convert `
(&iter)->std::_List_iterator<_Tp, _Ref,
_Ptr>::eek:perator*() const [with _Tp =
SomeClass, _Ref = const SomeClass&, _Ptr = const
SomeClass*]()' to `SomeClass&'

SomeClass is a std::list of a user-defined class.

The error gets raised on the return statement of this
function: SomeClass& AnotherClass::get_element(const
string& tag) const {
std::list<SomeClass>::const_iterator iter =
_elements.begin();

// This isn't very well written, and I'm sure
there's better // ways of doing it. Feel free to
give me ideas on how to improve it. while (iter !=
_elements.end()) {
if (iter->get_member("tag") == tag)
return *iter; // error rasied here
++iter;
}
// throw exception cuz not found
}

Your 'const' is all screwed up again. The return value
of this function is 'SomeClass&', a reference to
non-const SomeClass object. The 'iter' is declared as
'const_iterator', whose operator* (dereference operator)
yields a 'SomeClass const&', a reference to a const
SomeClass object. Of course it cannot convert a const ref
to a non-const ref.

Victor

Ah, I understand. So what's the correct thing to do here? (Can I return a
const reference?)
 
V

Victor Bazarov

Joe said:
Victor said:
Joe said:
Joe Laughlin wrote:


(file and class names changed to protect the innocent)

g++ -Wall -c file.cpp: In member function `std::string
Some_Class::get_member(const std::string&) const':
file.cpp:46: passing `const std::map<std::string,
std::string, std::less<std::string>,
std::allocator<std::pair<const std::string,
std::string> > >' as `this' argument of `_Tp&
std::map<_Key, _Tp, _Compare,
_Alloc>::eek:perator[](const _Key&) [with _Key =
std::string, _Tp = std::string, _Compare =
std::less<std::string>, _Alloc =
std::allocator<std::pair<const std::string, std::string>

]' discards qualifiers

I can't make heads or tails of this error. I'm guessing
it has something to do with calling a non-const function
on some const object. Any ideas?

The function SomeClass::get_member is:

std::string SomeClass::get_member(const std::string
&name) const {
return _member[name];
}

where _member is a std::map<std::string, std::string>.


Here's another one, probably related to my lack of
understanding about the STL. (These error messages sure
aren't very clear!)


Error is:
could not convert `
(&iter)->std::_List_iterator<_Tp, _Ref,
_Ptr>::eek:perator*() const [with _Tp =
SomeClass, _Ref = const SomeClass&, _Ptr = const
SomeClass*]()' to `SomeClass&'

SomeClass is a std::list of a user-defined class.

The error gets raised on the return statement of this
function: SomeClass& AnotherClass::get_element(const
string& tag) const {
std::list<SomeClass>::const_iterator iter =
_elements.begin();

// This isn't very well written, and I'm sure
there's better // ways of doing it. Feel free to
give me ideas on how to improve it. while (iter !=
_elements.end()) {
if (iter->get_member("tag") == tag)
return *iter; // error rasied here
++iter;
}
// throw exception cuz not found
}

Your 'const' is all screwed up again. The return value
of this function is 'SomeClass&', a reference to
non-const SomeClass object. The 'iter' is declared as
'const_iterator', whose operator* (dereference operator)
yields a 'SomeClass const&', a reference to a const
SomeClass object. Of course it cannot convert a const ref
to a non-const ref.

Victor


Ah, I understand. So what's the correct thing to do here? (Can I return a
const reference?)

You can of course. I don't know if your algorithm allows you to, though.
Why did you need a non-const ref before?

V
 
J

Joe Laughlin

These weird errors just keep on coming! Thanks everyone again for your
help.

Please don't tell me this error is because of const again... :-( But I'd
wager it is.


// 6-9 from Accelerated C++
// Use library algorithm to cat all elements of a vector<string>

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>

int main()
{
std::vector<std::string> vec;
vec.push_back("Hi!");
vec.push_back(" How ");
vec.push_back("are ");
vec.push_back("you ");
vec.push_back("doing?");

std::string new_string;

copy(vec.begin(), vec.end(), std::back_inserter(new_string));

std::cout << new_string << std::endl;

return 0;
}


g++ -Wall -pedantic -o 6-9 6-9.cpp
/usr/include/c++/3.2.2/bits/stl_algobase.h: In function `_OutputIter
std::__copy(_RandomAccessIter, _RandomAccessIter, _OutputIter,
std::random_access_iterator_tag) [with _RandomAccessIter = std::string*,
_OutputIter = std::back_insert_iterator<std::string>]':
/usr/include/c++/3.2.2/bits/stl_algobase.h:260: instantiated from
`_OutputIter std::__copy_aux2(_InputIter, _InputIter, _
OutputIter, __false_type) [with _InputIter = std::string*, _OutputIter =
std::back_insert_iterator<std::string>]'
/usr/include/c++/3.2.2/bits/stl_algobase.h:303: instantiated from
`_OutputIter std::__copy_ni2(_InputIter, _InputIter, _O
utputIter, __false_type) [with _InputIter = std::string*, _OutputIter =
std::back_insert_iterator<std::string>]'
/usr/include/c++/3.2.2/bits/stl_algobase.h:314: instantiated from
`_OutputIter std::__copy_ni1(_InputIter, _InputIter, _O
utputIter, __true_type) [with _InputIter =
__gnu_cxx::__normal_iterator<std::string*, std::vector<std::string,
std::allocat
or<std::string> > >, _OutputIter = std::back_insert_iterator<std::string>]'
/usr/include/c++/3.2.2/bits/stl_algobase.h:349: instantiated from
`_OutputIter std::copy(_InputIter, _InputIter, _OutputI
ter) [with _InputIter = __gnu_cxx::__normal_iterator<std::string*,
std::vector<std::string, std::allocator<std::string> > >
, _OutputIter = std::back_insert_iterator<std::string>]'
6-9.cpp:22: instantiated from here
/usr/include/c++/3.2.2/bits/stl_algobase.h:241: no match for `
std::back_insert_iterator<std::string>& = std::basic_string<char,
std::char_traits<char>, std::allocator<char> >&' operator
/usr/include/c++/3.2.2/bits/stl_iterator.h:355: candidates are:
std::back_insert_iterator<_Container>&

std::back_insert_iterator<_Container>::eek:perator=(_Container::const_reference
)
[with _Container = std::string]
/usr/include/c++/3.2.2/bits/stl_iterator.h:330:
std::back_insert_iterator<std::string>&
std::back_insert_iterator<std::string>::eek:perator=(const
std::back_insert_iterator<std::string>&)
 
M

Mike Wahler

Joe Laughlin said:
These weird errors just keep on coming! Thanks everyone again for your
help.

Please don't tell me this error is because of const again... :-( But I'd
wager it is.

Not this time. :)
See below.
// 6-9 from Accelerated C++
// Use library algorithm to cat all elements of a vector<string>

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>

int main()
{
std::vector<std::string> vec;
vec.push_back("Hi!");
vec.push_back(" How ");
vec.push_back("are ");
vec.push_back("you ");
vec.push_back("doing?");

std::string new_string;

copy(vec.begin(), vec.end(), std::back_inserter(new_string));

std::cout << new_string << std::endl;

return 0;
}


g++ -Wall -pedantic -o 6-9 6-9.cpp
/usr/include/c++/3.2.2/bits/stl_algobase.h: In function `_OutputIter
std::__copy(_RandomAccessIter, _RandomAccessIter, _OutputIter,
std::random_access_iterator_tag) [with _RandomAccessIter = std::string*,
_OutputIter = std::back_insert_iterator<std::string>]':
/usr/include/c++/3.2.2/bits/stl_algobase.h:260: instantiated from
`_OutputIter std::__copy_aux2(_InputIter, _InputIter, _
OutputIter, __false_type) [with _InputIter = std::string*, _OutputIter =
std::back_insert_iterator<std::string>]'
/usr/include/c++/3.2.2/bits/stl_algobase.h:303: instantiated from
`_OutputIter std::__copy_ni2(_InputIter, _InputIter, _O
utputIter, __false_type) [with _InputIter = std::string*, _OutputIter =
std::back_insert_iterator<std::string>]'
/usr/include/c++/3.2.2/bits/stl_algobase.h:314: instantiated from
`_OutputIter std::__copy_ni1(_InputIter, _InputIter, _O
utputIter, __true_type) [with _InputIter =
__gnu_cxx::__normal_iterator<std::string*, std::vector<std::string,
std::allocat
or<std::string> > >, _OutputIter =
std::back_insert_iterator said:
/usr/include/c++/3.2.2/bits/stl_algobase.h:349: instantiated from
`_OutputIter std::copy(_InputIter, _InputIter, _OutputI
ter) [with _InputIter = __gnu_cxx::__normal_iterator<std::string*,
std::vector<std::string, std::allocator<std::string> > >
, _OutputIter = std::back_insert_iterator<std::string>]'
6-9.cpp:22: instantiated from here
/usr/include/c++/3.2.2/bits/stl_algobase.h:241: no match for `
std::back_insert_iterator<std::string>& = std::basic_string<char,
std::char_traits<char>, std::allocator<char> >&' operator
/usr/include/c++/3.2.2/bits/stl_iterator.h:355: candidates are:
std::back_insert_iterator<_Container>&
std::back_insert_iterator said:
)
[with _Container = std::string]
/usr/include/c++/3.2.2/bits/stl_iterator.h:330:
std::back_insert_iterator<std::string>&
std::back_insert_iterator<std::string>::eek:perator=(const
std::back_insert_iterator<std::string>&)

'back_insert_iterator' requires that the container type specified by
its template argument defines members 'push_back()' and 'value_type'.
'std::string' defines the latter, but not the former.

IOW you cannot use 'back_insert_iterator' with a 'std::string'.
('std::string', while sharing much commonality with them, isn't
strictly a 'container').

-Mike
 
J

Joe Laughlin

Mike said:
Joe Laughlin said:
These weird errors just keep on coming! Thanks everyone
again for your help.

Please don't tell me this error is because of const
again... :-( But I'd wager it is.

Not this time. :)
See below.
// 6-9 from Accelerated C++
// Use library algorithm to cat all elements of a
vector<string>

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>

int main()
{
std::vector<std::string> vec;
vec.push_back("Hi!");
vec.push_back(" How ");
vec.push_back("are ");
vec.push_back("you ");
vec.push_back("doing?");

std::string new_string;

copy(vec.begin(), vec.end(),
std::back_inserter(new_string));

std::cout << new_string << std::endl;

return 0;
}


g++ -Wall -pedantic -o 6-9 6-9.cpp
/usr/include/c++/3.2.2/bits/stl_algobase.h: In function
`_OutputIter std::__copy(_RandomAccessIter,
_RandomAccessIter, _OutputIter,
std::random_access_iterator_tag) [with
_RandomAccessIter = std::string*, _OutputIter =
std::back_insert_iterator<std::string>]':
/usr/include/c++/3.2.2/bits/stl_algobase.h:260:
instantiated from `_OutputIter
std::__copy_aux2(_InputIter, _InputIter, _
OutputIter, __false_type) [with _InputIter =
std::string*, _OutputIter =
std::back_insert_iterator<std::string>]'
/usr/include/c++/3.2.2/bits/stl_algobase.h:303:
instantiated from `_OutputIter
std::__copy_ni2(_InputIter, _InputIter, _O
utputIter, __false_type) [with _InputIter =
std::string*, _OutputIter =
std::back_insert_iterator<std::string>]'
/usr/include/c++/3.2.2/bits/stl_algobase.h:314:
instantiated from `_OutputIter
std::__copy_ni1(_InputIter, _InputIter, _O
utputIter, __true_type) [with _InputIter =
__gnu_cxx::__normal_iterator<std::string*,
std::vector<std::string, std::allocat
or<std::string> > >, _OutputIter =
std::back_insert_iterator said:
/usr/include/c++/3.2.2/bits/stl_algobase.h:349:
instantiated from `_OutputIter std::copy(_InputIter,
_InputIter, _OutputI
ter) [with _InputIter =
__gnu_cxx::__normal_iterator<std::string*,
std::vector<std::string, std::allocator<std::string> > >
, _OutputIter = std::back_insert_iterator<std::string>]'
6-9.cpp:22: instantiated from here
/usr/include/c++/3.2.2/bits/stl_algobase.h:241: no
match for ` std::back_insert_iterator<std::string>& =
std::basic_string<char, std::char_traits<char>,
std::allocator<char> >&' operator
/usr/include/c++/3.2.2/bits/stl_iterator.h:355:
candidates are: std::back_insert_iterator<_Container>&
std::back_insert_iterator said:
)
[with _Container = std::string]
/usr/include/c++/3.2.2/bits/stl_iterator.h:330:
std::back_insert_iterator<std::string>&


std::back_insert_iterator<std::string>::eek:perator=(const
std::back_insert_iterator<std::string>&)

'back_insert_iterator' requires that the container type
specified by its template argument defines members
'push_back()' and 'value_type'. 'std::string' defines the
latter, but not the former.

IOW you cannot use 'back_insert_iterator' with a
'std::string'. ('std::string', while sharing much
commonality with them, isn't strictly a 'container').

-Mike

Argh.

From "Accelerated C++", pg 121:

"back_inserter(c)
Yields an iterator on the container c that appends elements to c. The
container must support push_back, which the list, vector, and the string
types all do."
 
J

Joe Laughlin

Joe said:
Mike said:
Joe Laughlin said:
Joe Laughlin wrote:


These weird errors just keep on coming! Thanks everyone
again for your help.

Please don't tell me this error is because of const
again... :-( But I'd wager it is.

Not this time. :)
See below.
// 6-9 from Accelerated C++
// Use library algorithm to cat all elements of a
vector<string>

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>

int main()
{
std::vector<std::string> vec;
vec.push_back("Hi!");
vec.push_back(" How ");
vec.push_back("are ");
vec.push_back("you ");
vec.push_back("doing?");

std::string new_string;

copy(vec.begin(), vec.end(),
std::back_inserter(new_string));

std::cout << new_string << std::endl;

return 0;
}


g++ -Wall -pedantic -o 6-9 6-9.cpp
/usr/include/c++/3.2.2/bits/stl_algobase.h: In function
`_OutputIter std::__copy(_RandomAccessIter,
_RandomAccessIter, _OutputIter,
std::random_access_iterator_tag) [with
_RandomAccessIter = std::string*, _OutputIter =
std::back_insert_iterator<std::string>]':
/usr/include/c++/3.2.2/bits/stl_algobase.h:260:
instantiated from `_OutputIter
std::__copy_aux2(_InputIter, _InputIter, _
OutputIter, __false_type) [with _InputIter =
std::string*, _OutputIter =
std::back_insert_iterator<std::string>]'
/usr/include/c++/3.2.2/bits/stl_algobase.h:303:
instantiated from `_OutputIter
std::__copy_ni2(_InputIter, _InputIter, _O
utputIter, __false_type) [with _InputIter =
std::string*, _OutputIter =
std::back_insert_iterator<std::string>]'
/usr/include/c++/3.2.2/bits/stl_algobase.h:314:
instantiated from `_OutputIter
std::__copy_ni1(_InputIter, _InputIter, _O
utputIter, __true_type) [with _InputIter =
__gnu_cxx::__normal_iterator<std::string*,
std::vector<std::string, std::allocat
or<std::string> > >, _OutputIter =
std::back_insert_iterator said:
/usr/include/c++/3.2.2/bits/stl_algobase.h:349:
instantiated from `_OutputIter std::copy(_InputIter,
_InputIter, _OutputI
ter) [with _InputIter =
__gnu_cxx::__normal_iterator<std::string*,
std::vector<std::string, std::allocator<std::string> > >
, _OutputIter = std::back_insert_iterator<std::string>]'
6-9.cpp:22: instantiated from here
/usr/include/c++/3.2.2/bits/stl_algobase.h:241: no
match for ` std::back_insert_iterator<std::string>& =
std::basic_string<char, std::char_traits<char>,
std::allocator<char> >&' operator
/usr/include/c++/3.2.2/bits/stl_iterator.h:355:
candidates are: std::back_insert_iterator<_Container>&
std::back_insert_iterator said:
)
[with _Container = std::string]
/usr/include/c++/3.2.2/bits/stl_iterator.h:330:
std::back_insert_iterator<std::string>&


std::back_insert_iterator<std::string>::eek:perator=(const
std::back_insert_iterator<std::string>&)

'back_insert_iterator' requires that the container type
specified by its template argument defines members
'push_back()' and 'value_type'. 'std::string' defines the
latter, but not the former.

IOW you cannot use 'back_insert_iterator' with a
'std::string'. ('std::string', while sharing much
commonality with them, isn't strictly a 'container').

-Mike

Argh.

From "Accelerated C++", pg 121:

"back_inserter(c)
Yields an iterator on the container c that appends
elements to c. The container must support push_back,
which the list, vector, and the string types all do."

So, was the book correct? Or wrong?
 
M

Mike Wahler

Joe Laughlin said:
So, was the book correct? Or wrong?

I think it's wrong. As far as I can tell from the standard,
'std::basic_string<>' is not required to provide 'push_back()',
but neither is it prohibited from doing so.

Of course I invite anyone else to give their interpretation,
so we can know for sure.

I scanned the AC++ errata pages, but I don't see this issue
mentioned.

Anyone else?

-Mike
 
B

Buster

Mike said:
I think it's wrong. As far as I can tell from the standard,
'std::basic_string<>' is not required to provide 'push_back()',
but neither is it prohibited from doing so.

ISO/IEC 14882 1998, p385

// 21.3.5: modifiers
....
void push_back (charT);
 
M

Mike Wahler

Buster said:
ISO/IEC 14882 1998, p385

// 21.3.5: modifiers
...
void push_back (charT);

But that's the *only* mention of it. For all the other
member functions, there is a description of behavior.
Not for this one. ???

-Mike
 
R

Rob Williscroft

Mike Wahler wrote in @newsread3.news.pas.earthlink.net in comp.lang.c++:
But that's the *only* mention of it. For all the other
member functions, there is a description of behavior.
Not for this one. ???

21.3/2

The class template basic_string conforms to the requirements of a
Sequence, as specified in (23.1.1). Additionally, because the
iterators supported by basic_string are random access iterators
(24.1.5), basic_string conforms to the the requirements of a
Reversible Container, as specified in (23.1).

Table 68 - Optional Sequence operations (23.1.1/12) describes push_back.
Presunmably its only because its optional that its mentioned in 21.3.5
at all.

Rob.
 
J

Jerry Coffin

[ ... ]
But that's the *only* mention of it. For all the other
member functions, there is a description of behavior.
Not for this one. ???

Theoretically, it's handled by ($21.3/2):

The template class basic_string conforms to the requirements
of a Sequence, as specified in (23.1.1).

Unfortunately, 23.1.1/12 also only mentions the existence of
push_back, and leaves describing it in any detail for the individual
container classes that provide it -- but (of course) not including
string...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top