Can't use STL algorithms and binders with function that has referenceparameter

M

massysett

Hello,

I've got a couple of simple functions to examine a vector of strings,
removing from the vector strings that do not begin with a particular
string. They compile just fine when they look like this:

#include <algorithm>
#include <functional>

bool startswith(std::string subject, std::string test)
{
return (subject.substr(0, test.length()) == test);
}

std::vector<std::string> matchAbbrev(std::vector<std::string> strings,
const std::string& abbrev)
{
// isolate all words with abbrev as a prefix
// Takes the list of all strings and removes strings that do NOT
// start with abbrev.
std::vector<std::string>::iterator it =
std::remove_if(strings.begin(), strings.end(),
std::not1(std::bind2nd(std::ptr_fun(startswith), abbrev)));

strings.erase(it, strings.end());
return strings;
}

However, if I change the parameter list of the first function so it
looks like this:

bool startswith(std::string& subject, std::string& test)

(note the addition of the references) it won't compile and I get a
slew of errors. Why? Maybe I could work around this with pointers,
which would not be particularly pretty...
 
W

werasm

bool startswith(std::string& subject, std::string& test)

(note the addition of the references) it won't compile and I get a
slew of errors. Why? Maybe I could work around this with pointers,
which would not be particularly pretty...

You've omitted to included <vector> and <string> and for that
reason your code does not compile (at least the posted code).

Apart from that, use const references. Changing the binary
function declaration to:

bool startswith(
const std::string& subject, const std::string& test)

seems to do the trick, which is more correct anyway because
comparison does not imply modification, not?

Regards,

Werner
 
M

massysett

You've omitted to included <vector> and <string> and for that
reason your code does not compile (at least the posted code).

Yes, thanks for pointing that out (only noticed right after I
posted...)
Apart from that, use const references. Changing the binary
function declaration to:

Unfortunately that doesn't work for me--actually my original
implementation used constant references. I get a slew of errors,
starting with

/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/
stl_function.h:435: error: forming reference to reference type 'const
std::string&'

I'm on g++ 4.1.2 as you can see...
 
A

Abhishek Padmanabh

Hello,

I've got a couple of simple functions to examine a vector of strings,
removing from the vector strings that do not begin with a particular
string. They compile just fine when they look like this:

#include <algorithm>
#include <functional>

bool startswith(std::string subject, std::string test)
{
return (subject.substr(0, test.length()) == test);

}

std::vector<std::string> matchAbbrev(std::vector<std::string> strings,
const std::string& abbrev)
{
// isolate all words with abbrev as a prefix
// Takes the list of all strings and removes strings that do NOT
// start with abbrev.
std::vector<std::string>::iterator it =
std::remove_if(strings.begin(), strings.end(),
std::not1(std::bind2nd(std::ptr_fun(startswith), abbrev)));

strings.erase(it, strings.end());
return strings;

}

However, if I change the parameter list of the first function so it
looks like this:

bool startswith(std::string& subject, std::string& test)

(note the addition of the references) it won't compile and I get a
slew of errors. Why? Maybe I could work around this with pointers,
which would not be particularly pretty...

Use std::bind or tr1::bind instead of bind2nd. bind2nd and bind1st
work only for const arguments (or if they are passed by value). If you
make the arguments non-const, they fail. If you use a functor the
operator() need to be const as well. boost::bind/tr1::bind are the
solution to this.
 
W

werasm



O, my apology if that is the case. I should probably tell
you that I've used bind1st and bind2nd quite some time ago
but it worked with references then, but I must have used
another lib than you. Currently I'm using gcc 4.1.2 but I
use boost::bind for quite some time now and STL algorithms
has become a breeze. :). You should try it too. Actually,
I think the libc++ is not distributed with tr1::bind which
works much better. You should have a look.

W
 
W

werasm

O, my apology if that is the case. I should probably tell
you that I've used bind1st and bind2nd quite some time ago
but it worked with references then, but I must have used
another lib than you. Currently I'm using gcc 4.1.2 but I
use boost::bind for quite some time now and STL algorithms
has become a breeze. :). You should try it too. Actually,
I think the libc++ is not distributed with tr1::bind which

I meant [is] and not [is not]
 

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

Forum statistics

Threads
473,961
Messages
2,570,131
Members
46,689
Latest member
liammiller

Latest Threads

Top