Interpreting error messages (gcc)

G

Greg Buchholz

I'm wondering if anyone has advice for figuring out error messages
produced by g++. The programs below works fine, until I uncomment out
the two "transform" lines. Then it points me to line 24 (where the
second "bind1st" is) and results in an error message complaining about
no match for 'operator=' and/or problems with 'back_insert_iterator'
(see the entire error message reproduced below). Do I need a cast
somewhere to keep the type-checker happy? Is it a template problem?
Since I'm working with standard containers, I can't imagine that
there's no assignment operator defined. Is there a subtle mistake I've
made, or am I doing something obviously wrong? In addition to figuring
out this particular error, I'd also appreciate general strategies for
figuring out compiler messages produces by g++. Do commercial products
do a better job in the error message department?

Thanks,

Greg Buchholz


#include <list>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <functional>

using namespace std;

list<string> aux(list<string> ps, string n);

int main()
{

list<string> f, out;

f.push_back("foo");
f.push_back("bar");
f.push_back("baz");

list<string> g = bind1st(ptr_fun(*aux),f)("TEST");

//transform(f.begin(),f.end(),back_inserter(out),
// bind1st(ptr_fun(aux),f));

copy(g.begin(),g.end(),ostream_iterator<string>(cout, " "));
cout << endl;

return 0;
}

list<string> aux(list<string> ps, string n)
{
list<string> out;
transform(ps.begin(),ps.end(),back_inserter(out),
bind1st(plus<string>(),n));
return out;
}


/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/bits/stl_algo.h:
In function `_OutputIterator std::transform(_InputIterator,
_InputIterator, _OutputIterator, _UnaryOperation) [with _InputIterator
=
std::_List_iterator<std::string>, _OutputIterator =
std::back_insert_iterator<std::list<std::string,
std::allocator<std::string> > >, _UnaryOperation =
std::binder1st<std::pointer_to_binary_function<std::list<std::string,
std::allocator<std::string> >, std::string, std::list<std::string,
std::allocator<std::string> > > >]': test3.cpp:24: instantiated from
here
/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/bits/stl_algo.h:789:
error: no match for 'operator=' in
'(&__result)->std::back_insert_iterator<_Container>::eek:perator* [with
_Container = std::list<std::string, std::allocator<std::string> >]() =
std::binder1st<_Operation>::eek:perator()(typename
_Operation::second_argument_type&) const [with _Operation =
std::pointer_to_binary_function<std::list<std::string,
](((std::string&)(+(&__first)->std::_List_iterator<_Tp>::eek:perator*
[with _Tp = std::string]())))'
/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/bits/stl_iterator.h:363:
note: candidates are: std::back_insert_iterator<_Container>&
std::back_insert_iterator<_Container>::eek:perator=(typename
_Container::const_reference) [with _Container = std::list<std::string,
std::allocator<std::string> >]
/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/bits/stl_iterator.h:338:
note: std::back_insert_iterator<std::list<std::string,
std::allocator<std::string> > >&
std::back_insert_iterator<std::list<std::string,
std::allocator<std::string> > >::eek:perator=(const
std::back_insert_iterator<std::list<std::string,
std::allocator<std::string> > >&)
 
M

Mark P

Greg said:
I'm wondering if anyone has advice for figuring out error messages
produced by g++. The programs below works fine, until I uncomment out
the two "transform" lines. Then it points me to line 24 (where the
second "bind1st" is) and results in an error message complaining about
no match for 'operator=' and/or problems with 'back_insert_iterator'
(see the entire error message reproduced below). Do I need a cast
somewhere to keep the type-checker happy? Is it a template problem?
Since I'm working with standard containers, I can't imagine that
there's no assignment operator defined. Is there a subtle mistake I've
made, or am I doing something obviously wrong? In addition to figuring
out this particular error, I'd also appreciate general strategies for
figuring out compiler messages produces by g++. Do commercial products
do a better job in the error message department?

Thanks,

Greg Buchholz

I'm with you that the error messages involving STL classes can be pretty
hard to parse. The problem in your case is that the function aux
returns a list<string> and your output iterator in transform,
back_inserter(out), expects to receive strings. It's writing them
*into* a list of strings, but the things being written need to be strings.

Changing the definition of out to, for example:

list<list<string> > out;

will produce compilable code.

-Mark
#include <list>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <functional>

using namespace std;

list<string> aux(list<string> ps, string n);

int main()
{

list<string> f, out;

f.push_back("foo");
f.push_back("bar");
f.push_back("baz");

list<string> g = bind1st(ptr_fun(*aux),f)("TEST");

//transform(f.begin(),f.end(),back_inserter(out),
// bind1st(ptr_fun(aux),f));

copy(g.begin(),g.end(),ostream_iterator<string>(cout, " "));
cout << endl;

return 0;
}

list<string> aux(list<string> ps, string n)
{
list<string> out;
transform(ps.begin(),ps.end(),back_inserter(out),
bind1st(plus<string>(),n));
return out;
}


/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/bits/stl_algo.h:
In function `_OutputIterator std::transform(_InputIterator,
_InputIterator, _OutputIterator, _UnaryOperation) [with _InputIterator
=
std::_List_iterator<std::string>, _OutputIterator =
std::back_insert_iterator<std::list<std::string,
std::allocator<std::string> > >, _UnaryOperation =
std::binder1st<std::pointer_to_binary_function<std::list<std::string,
std::allocator<std::string> >, std::string, std::list<std::string,
std::allocator<std::string> > > >]': test3.cpp:24: instantiated from
here
/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/bits/stl_algo.h:789:
error: no match for 'operator=' in
'(&__result)->std::back_insert_iterator<_Container>::eek:perator* [with
_Container = std::list<std::string, std::allocator<std::string> >]() =
std::binder1st<_Operation>::eek:perator()(typename
_Operation::second_argument_type&) const [with _Operation =
std::pointer_to_binary_function<std::list<std::string,
](((std::string&)(+(&__first)->std::_List_iterator<_Tp>::eek:perator*

[with _Tp = std::string]())))'
/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/bits/stl_iterator.h:363:
note: candidates are: std::back_insert_iterator<_Container>&
std::back_insert_iterator<_Container>::eek:perator=(typename
_Container::const_reference) [with _Container = std::list<std::string,
std::allocator<std::string> >]
/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/bits/stl_iterator.h:338:
note: std::back_insert_iterator<std::list<std::string,
std::allocator<std::string> > >&
std::back_insert_iterator<std::list<std::string,
std::allocator<std::string> > >::eek:perator=(const
std::back_insert_iterator<std::list<std::string,
std::allocator<std::string> > >&)
 
V

Victor Bazarov

Greg said:
I'm wondering if anyone has advice for figuring out error messages
produced by g++. [...]

RTFM what 'transform' does. Especially what the predicate is supposed
to do. Try to imagine what "normal" C++ code 'transform' corresponds to.
IOW, try to "unroll" to loop behind it.

V
 
G

Greg Buchholz

Mark said:
I'm with you that the error messages involving STL classes can be pretty
hard to parse. The problem in your case is that the function aux
returns a list<string> and your output iterator in transform,
back_inserter(out), expects to receive strings. It's writing them
*into* a list of strings, but the things being written need to be strings.

Changing the definition of out to, for example:

list<list<string> > out;

will produce compilable code.

Arrrgh, of course. Good catch. But I'm curious, how did you spot
the problem? Did you just glance at the code and recognize the type
error? Or was it your experience that lead you to suspect that
complicated error messages are probably simple type problems? Or did
the actual error message help you out in any way?

Thanks again,

Greg Buchholz
 
M

Mark P

Greg said:
Arrrgh, of course. Good catch. But I'm curious, how did you spot
the problem? Did you just glance at the code and recognize the type
error? Or was it your experience that lead you to suspect that
complicated error messages are probably simple type problems? Or did
the actual error message help you out in any way?

Thanks again,

Greg Buchholz

The error message got me to the problematic line but I didn't get far
trying to make sense of the many nested angle brackets. What stuck out
most prominently is that you were using the same back_inserter in two
obviously different contexts-- from there you can see how I came across
the error.
 
B

Barbier de Reuille Pierre

The error message got me to the problematic line but I didn't get far
trying to make sense of the many nested angle brackets. What stuck
out most prominently is that you were using the same back_inserter in
two obviously different contexts-- from there you can see how I came
across the error.

And then, now it is quite understandable (ie. you can *quickly* find
the information). I mean, you find very easily the templates involved,
and the arguments follows. Previous versions (and it is also true for
other compilers I used) just gave you the template with all the
arguments between the <> ...

But then for your message, you can find the error here (although your
case is quite complex) :

1) /usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/bits/stl_algo.h:789:
error: no match for 'operator=' in

2) '(&__result)->std::back_insert_iterator<_Container>::eek:perator*

3) [with _Container = std::list said:

3) () = std::binder1st<_Operation>::eek:perator()(typename
_Operation::second_argument_type&) const

4) [with _Operation =
std::pointer_to_binary_function<std::list<std::string,

5) (((std::string&)(+(&__first)->std::_List_iterator<_Tp>::eek:perator*
[with _Tp = std::string]())))'

So the first line tells you the operator = *does* exist, but is not
overloaded with the type used here. The following lines correspond to
the expression. Second line gives you the faulty template ... a
back_inserter of some _Container ... here a list of string. Line 3
tells you the problem is when assigning the result of the binder1st.
And, at last, line 4 you have the operation involved and you can see
the return type (i.e. the first argument of the
pointer_to_binary_function) is a list of string ... instead of a string.

I may say it takes quite some time to get used to errors with
templates. If I would recommend something : split the important line in
many other lines like I did here, but only if you cannot guess what the
error is just from the first lines (as Mark did).

Pierre
 

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,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top