Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to bind a template function

Tags:

c++

boost

Hi to all you boost gurus out there!

I want to find a certain element in a vector of strings, ignoring case:

#include <iostream>
#include <string>
#include <vector>
#include "boost/algorithm/string.hpp"
#include "boost/bind.hpp"

using std::string;
using std::vector;

bool icmp(const string& str1, const string& str2)
{
    return boost::iequals(str1, str2);
}

int main(int argc, char* argv[])
{
    vector<string> vec;
    vec.push_back("test");

//  if (std::find_if(vec.begin(), vec.end(), boost::bind(&boost::iequals<string,string>, "TEST", _1)) != vec.end()) <-- does not compile
    if (std::find_if(vec.begin(), vec.end(), boost::bind(&icmp, "TEST", _1)) != vec.end())
        std::cout << "found" << std::endl;

    return 0;
}

This is working fine so far, but what I would like to know is, if it is possible to get rid of the extra function (icmp()) and invoke iequals (template function) directly (like in the commented line).

Thanks in advance!

like image 467
raines Avatar asked Nov 09 '11 16:11

raines


3 Answers

Adding the template params and the default locale parameter works on my machine.

if (std::find_if(vec.begin(), vec.end(), boost::bind(&boost::iequals<string,string>, "TEST", _1, std::locale())) != vec.end())
        std::cout << "found" << std::endl;

Compiler is VS2010.

like image 78
mkaes Avatar answered Nov 18 '22 08:11

mkaes


I'm sure this is not what you're hoping for, but this appears to be the only fix I can work out
(with g++ c++03 mode):

typedef bool (*fptr)(const std::string&, const std::string&);


if (std::find_if(vec.begin(), vec.end(), 
    boost::bind((fptr) &boost::iequals<string,string>, "TEST", _1)
) != vec.end())
like image 26
sehe Avatar answered Nov 18 '22 09:11

sehe


Using boost lambda :)

#include <iostream>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <algorithm>
#include <vector>
using namespace std;
using namespace boost::lambda;

int main()
{
    vector<string> vec;
    vec.push_back("TEST");
    vec.push_back("test");

    vector<string>::iterator it;

    it = find_if(vec.begin(),vec.end(),_1 == "test");
    cout << *it << endl;

    return 0;
}
like image 2
Arunmu Avatar answered Nov 18 '22 07:11

Arunmu