boost::bind, boost::function

Sep 10, 2013 at 1:23pm
Hello,

I am not so experienced in STL/Boost and I want to use this code:
http://stackoverflow.com/a/11167563 to sort structures.

However, my compiler writes me this:

Could not find a match for 'ChainComparer<Citizen>::Chain<TComparer,TValueGetter>(boost::_bi::bind_t<const std::wstring &,boost::_mfi::dm<std::wstring,Citizen>,boost::_bi::list1<boost::arg<1> (*)()> >)'


Can you please explain, as I cant figure this myself, where is bad bind, template or something.

Thank you.
Last edited on Sep 10, 2013 at 1:24pm
Sep 10, 2013 at 2:17pm
You'd have to show the exact program you're tryng to compile, since the code posted on that link does not. Here's my quick attempt to fix the syntax errors:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/foreach.hpp>

template <typename T>
class ChainComparer {
public:

    typedef boost::function<bool(const T&, const T&)> TComparator;
    typedef TComparator EqualComparator;
    typedef TComparator CustomComparator;

    template <template <typename> class TComparer, typename TValueGetter>
    void Chain( const TValueGetter& getter ) {

        iComparers.push_back( std::make_pair(
            boost::bind( getter, _1 ) == boost::bind( getter, _2 ),
            boost::bind( TComparer<typename TValueGetter::result_type>(), boost::bind( getter, _1 ), boost::bind( getter, _2 ) )
        ) );
    }

    bool operator()( const T& lhs, const T& rhs ) {
        BOOST_FOREACH( const auto& comparer, iComparers ) {
            if( !comparer.first( lhs, rhs ) ) {
                return comparer.second( lhs, rhs );
            }
        }

        return false;
    }

private:
    std::vector<std::pair<EqualComparator, CustomComparator>> iComparers;
};

struct Citizen {
    std::wstring iFirstName;
    std::wstring iLastName;
};

int main() {
    ChainComparer<Citizen> cmp;
    cmp.Chain<std::less>( boost::bind( &Citizen::iLastName, _1 ) );
    cmp.Chain<std::less>( boost::bind( &Citizen::iFirstName, _1 ) );

    std::vector<Citizen> vec;
    std::sort( vec.begin(), vec.end(), cmp );
}


Sep 11, 2013 at 4:13am
you managed to guess program almost exactly, as i tried it first on very simple example :) just to be sure, here is my program after your change in class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <boost/bind.hpp>
#include <boost/function.hpp>

#include <vector>
#include <utility>
#include <string>

template <typename T>
class ChainComparer {
public:

    typedef boost::function<bool(const T&, const T&)> TComparator;
    typedef TComparator EqualComparator;
    typedef TComparator CustomComparator;

    template <template <typename> class TComparer, typename TValueGetter>
    void Chain( const TValueGetter& getter ) {

        iComparers.push_back( std::make_pair(
            boost::bind( getter, _1 ) == boost::bind( getter, _2 ),
			boost::bind( TComparer<typename TValueGetter::result_type>(), boost::bind( getter, _1 ), boost::bind( getter, _2 ) )
        ) );
    }

    bool operator()( const T& lhs, const T& rhs ) {
        BOOST_FOREACH( const auto& comparer, iComparers ) {
            if( !comparer.first( lhs, rhs ) ) {
                return comparer.second( lhs, rhs );
            }
        }

        return false;
    }

private:
    std::vector<std::pair<EqualComparator, CustomComparator> > iComparers;
};

struct Citizen {
	std::wstring iFirstName;
	std::wstring iLastName;
};

int main(int argc, char* argv[]) {

	ChainComparer<Citizen> cmp;
	cmp.Chain<std::less>( boost::bind( &Citizen::iLastName, _1 ) );
	cmp.Chain<std::less>( boost::bind( &Citizen::iFirstName, _1 ) );

	std::vector<Citizen> vec;
	std::sort( vec.begin(), vec.end(), cmp );


	return 0;
}


unfortunately, the error remains.
i have c++ builder xe4 (also unfortunately, in my work, cant change this with boost 1.39 (this i can change). any other advices?

thank you.
Last edited on Sep 11, 2013 at 5:33am
Sep 11, 2013 at 1:11pm
GNU g++ compiles that with no issues after adding the missing #include <boost/foreach.hpp> , and the version of IBM XL C++ I use doesn't support auto yet, but replacing it with iComparers's value type makes your code compile and run cleanly as well.

This is likely a compiler deficiency: boost is not even tested on Builder (the list of supported compilers is at the bottom of each release page: http://www.boost.org/users/history/version_1_54_0.html )

If this is for work, I would recommend trimming this down to a smallest example that reproduces the error and making Embarcadero fix the compiler, that's what you're paying them for. We make Oracle and IBM fix the bugs in their compilers routinely.

(PS: had to remove reference from ValueGetter::result_type to get this to compile on Oracle:
1
2
3
4
5
6
       iComparers.push_back( std::make_pair(
                        boost::bind( getter, _1 ) == boost::bind( getter, _2 ),
                        boost::bind( TComparer<
                             typename boost::remove_reference<typename TValueGetter::result_type>::type >(),
                                     boost::bind( getter, _1 ),
                                     boost::bind( getter, _2 ) )

try that on yours
Last edited on Sep 11, 2013 at 2:05pm
Sep 12, 2013 at 6:06am
thank you very much - it did not even come to my mind that fault could be here. i tried it with 64bit version of compiler and it can be compiled, so 32bit one is not good.

this is quite another thing but embarcadero seems to not care about "technical" things, only colors, design and other balast. they have boost 1.39 on 32bit compiler with almost no support of c++11. unfortunately i cant use 64bit one (most of c++11, boost 1.50) because we have customers with even windows 95 perhaps. i think if i get this bug to qc it could last there for years maybe but maybe i'll try.

anyway, thank you for your help, i will try some other way to get sorting comparator.
Topic archived. No new replies allowed.