1

I'm trying to store data from a file into a vector of objects and then sorting the data members but I'm getting the errors "Cannot determine which instance of overloaded function "sort" is intended". I've tried using lambdas with sort and also thought it might be the way I've created my comparison function (is it a.hour > b.hour or should I use a.getHour() and b.getHour()?) I actually want to sort the vector by both hours and minutes but testing it on only hours first doesn't seem to work. This is what I have so far

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>
using namespace std;

class time {
    int hour;
    int minute;
public:
    time(int h, int m) {
        hour = h;
        minute = m;
    }
    int getHour() { return hour; }
    int getMinute() { return minute; }
};

class Times {
    vector<time> t;
public:
    Times(string fileName) {
        //
    }

    void parse(ifstream& file) {
        //
        sort.(t.begin(), t.end(), lowerThan);
        //sort.(t.begin(), t.end(), [] (time& a, time& b) { return a.hour < b.hour; })
    }

    void display() {
        for (size_t i = 0; i < t.size(); i++) {
            cout << t[i].getHour() << ":" << t[i].getMinute() << endl;
        }
    }

    static bool lowerThan(time& a, time& b) { return a.getHour() < b.getHour(); }
};

int main() {
    Times times("File.txt");
    times.display();

    system("pause");
    return 0;
}
5
  • 3
    First you should not use using namespace std;. Second it looks like you have a typo. You have sort.(... not sort(... Commented Mar 15, 2016 at 17:50
  • Avoid using namespace std, Even more when you use name used in std as time. Commented Mar 15, 2016 at 17:52
  • Hi I've seen this in several places, but why to avoid using namespace std; ? Commented Mar 15, 2016 at 17:56
  • 1
    @FirstStep Check out the link in my comment Commented Mar 15, 2016 at 17:56
  • BTW, even without using namespace std;, it seems that your class time conflicts anyway with (C) function time, so use your own namespace, or rename your class time. Commented Mar 15, 2016 at 18:05

1 Answer 1

2

There are several issues in your code.

You should not use using namespace std; to avoid name clashing.

Moreover, unfortunately your time (lowercase) class conflicts with another time standard identifier. Just use Uppercase convention for naming classes.

In addition, you may want to mark your Time::getHour() and Time::getMinute() methods as const, since they don't modify the internal state of Time objects.

You also have a typo with sort calls, since you have a dot following sort.

And, in C++11/14, I'd suggest you using range-based for loops instead of explicit for with integer indexes.

I've refactored your code a little bit considering those aspects, and it now works, with both the lowerThan() static method and the lambda. Feel free to study it.

#include <algorithm>
#include <iostream>
#include <vector>

class Time {
    int hour;
    int minute;
public:
    Time(int h, int m) : hour(h), minute(m) {
    }

    int getHour() const { return hour; }
    int getMinute() const { return minute; }
};

class Times {
    std::vector<Time> t;

    static bool lowerThan(const Time& a, const Time& b) { 
        return a.getHour() < b.getHour(); 
    }

public:
    Times() {
        // Test data
        t.push_back(Time{10, 10});
        t.push_back(Time{9, 20});
        t.push_back(Time{8, 30});

        //std::sort(t.begin(), t.end(), lowerThan);

        std::sort(t.begin(), t.end(), [] (const Time& a, const Time& b) { 
            return a.getHour() < b.getHour(); 
        });
    }

    void display() {
        for (const auto& x : t) {
            std::cout << x.getHour() << ":" << x.getMinute() << '\n';
        }
    }
};

int main() {
    Times times;
    times.display();
}

Note also that if you define a custom operator< overload for sorting instances of the Time class, you can simply call std::sort() without any custom comparator, and your custom implementation of operator< is automatically picked up by the compiler:

class Time {
...
    friend bool operator<(const Time& a, const Time& b) {
        return a.getHour() < b.getHour();
        // ... or a more complete comparison, including minutes.
    }   
};

EDIT

As suggested in a comment by @DieterLücking, you can use std::tie() for the operator< implementation (live here on Ideone):

#include <tuple>  // for std::tie

class Time {
    ...
public:

friend bool operator<(const Time& a, const Time& b) {
    return std::tie(a.hour, a.minute) < std::tie(b.hour, b.minute);
}   

};
Sign up to request clarification or add additional context in comments.

1 Comment

For sorting: std::tie(a.hour, a.minute) < std::tie(b.hour, b.minute); or std::make_tuple(a.getHour(), a.getMinute()) < std::make_tuple(b.getHour(), b.getMinute()); if the operator is no friend

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.