Problem with equal_range

So I've got a problem and a question, so firstly I'll ask the question, how come I cannot define files(line 91) as
1
2
3
4
std::vector<std::vector<Sales_data>> files = {
		{("155", 15, 15), ("156", 15, 15)},
		{("155", 15, 15), ("154", 15, 15)},
		{("155", 15, 15)} };

When I do the above it gives me a no matching constructor error.

Now the problem is, if you compile the code below and enter 155, it never prints store 1.
The output is

store 0 sales: 155 15 225 15
store 2 sales: 155 15 225 15

and the expected output is

store 0 sales: 155 15 225 15
store 1 sales: 155 15 225 15
store 2 sales: 155 15 225 15


main.cpp
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
#include <iostream>
#include <string>
#include <vector>
#include <tuple>
#include <algorithm>

//#####################################################################################################################
//#####################################################################################################################

class Sales_data {
    friend bool operator==(const Sales_data &, const Sales_data &);
    friend bool operator!=(const Sales_data &, const Sales_data &);
    friend std::ostream &operator<<(std::ostream &, const Sales_data &);
public:
    // CONSTRUCTORS
    Sales_data(const std::string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue (p*n) {}
    Sales_data(const std::string &s = "") : Sales_data(s, 0, 0) {} // default and takes a string constructor
    Sales_data(unsigned n, double p) : Sales_data("", n, p) {}
    
    // assignment operators
    Sales_data& operator=(const std::string &);
    Sales_data& operator+=(const Sales_data &);

    // conversions
    explicit operator std::string() const { return bookNo; }
    explicit operator double() const { return revenue; };

    /// member functions
    std::string isbn() const { return bookNo; } // return the book number

    double avg_price() const { return (units_sold) ? revenue/units_sold : 0; } // for calculating the average price
private:
    std::string bookNo;      // for holding our book number/ISBN
    unsigned units_sold = 0; // for holding the amount of books sold
    double revenue = 0.0;    // for holding the price they were sold at
};

Sales_data operator+(const Sales_data &, const Sales_data &);
//#####################################################################################################################
//#####################################################################################################################




inline bool compareIsbn(const Sales_data &lhs, const Sales_data &rhs)
{
	return lhs.isbn() < rhs.isbn();
}

typedef std::tuple<std::vector<Sales_data>::size_type, std::vector<Sales_data>::const_iterator, 
		std::vector<Sales_data>::const_iterator> matches;

/*### findBook ###*/
std::vector<matches> findBook(const std::vector<std::vector<Sales_data>> &files, const std::string &book)
{
	std::vector<matches> ret;

	for (auto it = files.cbegin(); it != files.cend(); ++it)
	{

		auto found = std::equal_range(it->cbegin(), it->cend(), book, compareIsbn);
		if (found.first != found.second)
			ret.push_back(std::make_tuple(it - files.cbegin(), found.first, found.second));
	}
	return ret;
}

/*### reportResult ###*/
void reportResults(std::istream &in, std::ostream &os, const std::vector<std::vector<Sales_data>> &files)
{
	std::string s;
	while (in >> s)
	{
		auto trans = findBook(files, s);
		if (trans.empty())
		{
			std::cout << s << " not found in any stores" << std::endl;
			continue;
		}
		for (const auto &store : trans)
		{
			os << "store " << std::get<0>(store) << " sales: " 
				<< accumulate(std::get<1>(store), std::get<2>(store), Sales_data(s)) << std::endl;
		}
	}
}

/*### main ###*/
int main()
{
	std::vector<std::vector<Sales_data>> files = {
		{Sales_data("155", 15, 15), Sales_data("156", 15, 15)},
		{Sales_data("155", 15, 15), Sales_data("154", 15, 15)},
		{Sales_data("155", 15, 15)} };
	reportResults(std::cin, std::cout, files);

	return 1;
}




//#####################################################################################################################
//#####################################################################################################################
bool inline operator==(const Sales_data &lhs, const Sales_data &rhs)
{
    return lhs.isbn() == rhs.isbn() &&
           lhs.units_sold == rhs.units_sold &&
           lhs.revenue == rhs.revenue;
}
bool inline operator!=(const Sales_data &lhs, const Sales_data &rhs)
{
    return !(lhs == rhs);
}

Sales_data& Sales_data::operator=(const std::string &s)
{
    bookNo = s;
    return *this;
}

Sales_data& Sales_data::operator+=(const Sales_data &rhs)
{
	units_sold += rhs.units_sold; // add the amount of books sold
    revenue += rhs.revenue;       // add the revenue
  	return *this;                 // return the object that the funtion was called on
}

Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs)
{
	Sales_data sum = lhs; // sum for returning
    sum += rhs;
    return sum;           // return the combined object
} 

std::ostream &operator<<(std::ostream &os, const Sales_data &item)
{
	os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
    return os;        // return the output stream
}

Last edited on
http://www.cplusplus.com/reference/algorithm/equal_range/
The elements in the range shall already be sorted according to this same criterion (operator< or comp), or at least partitioned with respect to val.
However you've got ("155", 15, 15), ("154", 15, 15)
std::equal_range() requires that the input sequence be sorted according to the comparison function, otherwise its behavior is undefined.
Thanks ne555, missed that part.

Anything on my other question?

Thank you helios as well, your answer didn't pop up earlier.
Last edited on
use braces
Topic archived. No new replies allowed.