implementing lamda syntax

I've been staring at the syntax for implementing a lambda for quite a while and I'm hoping that someone can point out what I'm doing wrong.

The line that is breaking is right under the comment that says

//WHY ISN'T THIS WORKING?//

Below.

Any help is appreciated. Thank you for reading this.

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include "ProperFraction.hpp"
#include <iostream>
#include "Fraction.h"
#include <functional>
using namespace std;

template<typename Fraction>

//function
bool increasing_order(Fraction f1, Fraction f2)
{
    return Fraction::lessThan(f1,   f2);
}

//sort function takes array, size and here a pointer to a function
void mysort(Fraction arr[], int size, bool(*predicate)(Fraction, Fraction));

//using function pointer
void mysort(Fraction arr[], int size,
          bool(*predicate)(Fraction, Fraction))
{
    bool Swaps;
    Fraction temp;
    do
    {
        Swaps = false;
        for (int i = 0; i < size - 1; ++i)
            if (!predicate(arr[i], arr[i + 1]))
            {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
                Swaps = true;
            }
    } while (Swaps);
}
//functor

class my_order {
public:
    bool operator()(Fraction f1, Fraction f2) const
    {
        return Fraction::lessThan(f1, f2);
    }
};


template<typename Fraction>

void functorSort(Fraction arr[], int size,
            my_order predicate)
{
 
    
    bool Swaps;
    Fraction temp;
    do
    {
        Swaps = false;
        for (int i = 0; i < size - 1; ++i)
            if (!predicate(arr[i], arr[i + 1]))
            {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
                Swaps = true;
            }
    } while (Swaps);
}


template<typename Fraction>

void lambdaSort(Fraction arr[], int size,
                 function<bool(Fraction,Fraction)> anySort)
{
    
    
    bool Swaps;
    Fraction temp;
    do
    {
        Swaps = false;
        for (int i = 0; i < size - 1; ++i)
            if (!anySort(arr[i], arr[i + 1]))
            {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
                Swaps = true;
            }
    } while (Swaps);
}




int main(int argc, const char * argv[]) {
    
    cout <<" With a function Pointer \n";
    Fraction f1(1,2),f2(3,5),f3(5,7),f4(4,9),f5(3,4);
    Fraction arr[5] = {f1 ,f2, f3, f4, f5};
    cout << "before:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t"; (arr[i]).Fraction::print();
    }
    bool (*sortPtr)(Fraction,Fraction) = increasing_order;
    mysort(arr, 5, sortPtr);
    
    
    //mysort(arr, 5, my_order<Fraction>());
    
    cout << "\nafter:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t" ; arr[i].Fraction::print();
    }
    
    //Now with a Functor
    cout << "\n Now with a functor";
    my_order increasing;
    Fraction f6(3,2), f7(4,5), f8(6,7),f9(7,9),f10(8,4);
    Fraction arr2[5] = {f6 ,f7, f8, f9, f10};
    cout << "\nbefore:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t"; (arr2[i]).Fraction::print();
    }
    functorSort(arr2, 5, increasing);
    cout << "\nafter:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t" ; arr2[i].Fraction::print();
    }
    cout<< "\n Now for the Lambda";
    Fraction f11(9,2), f12(8,5),f13(4,7),f14(2,9),f15(5,4);
    Fraction arr3[5] = {f11,f12,f13,f14,f15};
    
    cout << "\nbefore:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t"; (arr3[i]).Fraction::print();
    }
    //WHY ISN'T THIS WORKING?
    lambdaSort(arr3,5,[](Fraction f1,Fraction f2) {return Fraction::lessThan(f1,f2);})
    
    
    cout << "\nafter:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t" ; arr3[i].Fraction::print();
    }
    cin.get();
    return 0;
}



The compiler says "No matching function call for lambdaSort" . I know that means that the way that I am calling the function doesn't match it's definition, but as I see it the parameters are:

1. An array of fraction objects
2. the size of the array
3. a function which takes two fractions as parameters and returns a bool.

I think that is what this lambda should do, but I'm obviously not doing somethign right.

I've got C++14 turned on in the build settings. I needed at least c++11 for the functional header stuff.


Last edited on
Please edit your post and make sure your code is [code]between code tags[/code] so that it has line numbers and syntax highlighting, as well as proper indentation.

Please copy and paste the exact error message and indicate which line it is referring to.

Is your compiler set to compile the code as C++11? Some compilers default to the older C++03.
Post exact compiler error. There should be at least several lines after yours "No matching function call for lambdaSort": is there ambiguity (which functions) or no viable candidates (which are closest and why there were rejected).

Alternatively you could post minimal example reproducing your problem: it should be a single snippet, if I try to compile it I would get same error message, it does not have any nonrelated code. Ideally you would post a link to online compiler attempt at building your code ( http://coliru.stacked-crooked.com/ )

/Users/aaron/Desktop/C++/Fractions/Fractions/main.cpp:148:5: No matching function for call to 'lambdaSort'


/Users/aaron/Desktop/C++/Fractions/Fractions/main.cpp:81:6: Candidate template ignored: could not match 'function<bool (type-parameter-0-0, type-parameter-0-0)>' against '(lambda at /Users/aaron/Desktop/C++/Fractions/Fractions/main.cpp:148:23)'
Just a quick question: does it work if you call it like lambdaSort<Fraction>(arr3,5,[](Fraction f1,Fraction f2) {return Fraction::lessThan(f1,f2);}) ?
That did it! Why?
And here it is cleaned up:

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

#include "ProperFraction.hpp"
#include <iostream>
#include "Fraction.h"
#include <functional>
using namespace std;

template<typename Fraction>

//function
bool increasing_order(Fraction f1, Fraction f2)
{
    return Fraction::lessThan(f1,   f2);
}

//functor

class my_order {
public:
    bool operator()(Fraction f1, Fraction f2) const
    {
        return Fraction::lessThan(f1, f2);
    }
};

template<typename Fraction>

void flexiSort(Fraction arr[], int size,
                 function<bool(Fraction,Fraction)> anySort)
{
    
    
    bool Swaps;
    Fraction temp;
    do
    {
        Swaps = false;
        for (int i = 0; i < size - 1; ++i)
            if (!anySort(arr[i], arr[i + 1]))
            {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
                Swaps = true;
            }
    } while (Swaps);
}




int main(int argc, const char * argv[]) {
    
    cout <<" With a function Pointer \n";
    Fraction f1(1,2),f2(3,5),f3(5,7),f4(4,9),f5(3,4);
    Fraction arr[5] = {f1 ,f2, f3, f4, f5};
    cout << "before:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t"; (arr[i]).Fraction::print();
    }
    bool (*sortPtr)(Fraction,Fraction) = increasing_order;
    //mysort(arr, 5, sortPtr);
    flexiSort<Fraction>(arr,5,sortPtr);
    
    //mysort(arr, 5, my_order<Fraction>());
    
    cout << "\nafter:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t" ; arr[i].Fraction::print();
    }
    
    //Now with a Functor
    cout << "\n Now with a functor";
    my_order increasing;
    Fraction f6(3,2), f7(4,5), f8(6,7),f9(7,9),f10(8,4);
    Fraction arr2[5] = {f6 ,f7, f8, f9, f10};
    cout << "\nbefore:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t"; (arr2[i]).Fraction::print();
    }
    //functorSort(arr2, 5, increasing);
    flexiSort<Fraction>(arr2,5,increasing);
    cout << "\nafter:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t" ; arr2[i].Fraction::print();
    }
    cout<< "\n Now for the Lambda";
    Fraction f11(9,2), f12(8,5),f13(4,7),f14(2,9),f15(5,4);
    Fraction arr3[5] = {f11,f12,f13,f14,f15};
    
    cout << "\nbefore:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t"; (arr3[i]).Fraction::print();
    }
    flexiSort<Fraction>(arr3,5,[](Fraction f1,Fraction f2) {return Fraction::lessThan(f1,f2);});
    
    cout << "\nafter:";
    for (int i = 0; i < 5;  ++i){
        cout <<"\t" ; arr3[i].Fraction::print();
    }
    cin.get();
    return 0;
}


output:
With a function Pointer
before: 1/2 3/5 5/7 4/9 3/4
after: 4/9 1/2 3/5 5/7 3/4
Now with a functor
before: 3/2 4/5 6/7 7/9 8/4
after: 7/9 4/5 6/7 3/2 8/4
Now for the Lambda
before: 9/2 8/5 4/7 2/9 5/4
after: 2/9 4/7 5/4 8/5 9/2
That did it! Why?
Because Lambda is not an std::function. Compiler cannot deduce type type of template parameter Fraction from arguments (as it expects std::function<bool(Fraction, Fraction)>, not lambda). By manually telling the type we avoid that problem. More common approach is to just make a whole predicate type a template parameter: if you will pass something wrong, it will lead to compie-time error anyway.
1
2
template<typename Fraction, typename Pred>
void lambdaSort(Fraction arr[], int size, Pred anySort)
O. That makes sense. Thank you very much for the help and insight.
Topic archived. No new replies allowed.