Как исправить код из упражнения 17.4 в книге Lippman C++ Primer ("Cannot convert argument...")?

Рейтинг: -1Ответов: 1Опубликовано: 21.03.2023

В главе 17 книги Lippman C++ Primer в упражнении 17.4 просят написать и проверить код который ранее обсуждался в главе. Весь код я переписал, написал также проверочную функцию main но в итоге при попытки компиляции показываются 2 ошибки:

Error   C2664   'bool (const Sales_data &,const Sales_data &)': cannot convert argument 2 from 'const _Ty' to 'const Sales_data &'
Error   C2664   'bool (const Sales_data &,const Sales_data &)': cannot convert argument 1 from 'const _Ty' to 'const Sales_data &'

Понимаю что вопрос достаточно обширный и не у всех будет желание даже скопировать и попробовать скомпилировать код, но надеюсь кто то да откликнется.

Пробовал также компилировать код двух других людей, но данные ошибки все равно не исчезали. Никак не могу понять как исправить данные ошибки.

Ссылка на код Sales_data.h

#include <iostream>
#include <utility>
#include <string>
#include <vector>
#include <sstream>
#include <tuple>
#include <fstream>
#include <algorithm>
#include <numeric>
#include "sales_data.h"

using namespace std;

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

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

vector<matches> find_book(const vector<vector<Sales_data>>& files, const string& book)
{
    vector<matches> ret;
    for (auto store_it = files.cbegin(); store_it != files.cend(); ++store_it)
    {
        auto found = equal_range(store_it->cbegin(), store_it->cend(), book, compare_isbn);
        if (found.first != found.second)
        {
            ret.push_back(make_tuple(store_it - files.cbegin(), found.first, found.second));
        }
    }
    return ret;
}

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

vector<Sales_data> get_data(ifstream& in)
{
    vector<Sales_data> ret;
    string data;
    while (getline(in, data)) {
        istringstream is(data);
        string bookNo;
        unsigned sold;
        double price;
        is >> bookNo >> sold >> price;
        ret.push_back(Sales_data(bookNo, sold, price));
    }
    sort(ret.begin(), ret.end(), compare_isbn);
    return ret;
}

int main()
{
    vector<vector<Sales_data>> files;
    ifstream store_one("./store_one.txt");
    ifstream store_two("./store_two.txt");
    ifstream store_three("./store_three.txt");
    files.push_back(get_data(store_one));
    files.push_back(get_data(store_two));
    files.push_back(get_data(store_three));
    report_results(cin, cout, files);

    return 0;
}

Текстовые файлы для проверки кода:

store_one.txt:

978-7-121-20038-0 5 128.0
978-7-121-20038-0 2 98.0
978-7-121-20038-0 1 100.0
978-0-553-21393-8 1 6.99
978-0-87779-855-2 2 6.99
978-7-121-12332-0 5 65.00
978-7-121-12332-0 1 59.00
978-7-121-12570-6 3 59.00
978-7-121-12570-6 3 49.00
978-7-5399-2460-1 1 15.00

store_two.txt:

978-7-121-20038-0 10 100.0
978-0-553-21393-8 1 6.99
978-0-87779-855-2 2 6.99
978-7-121-12332-0 5 65.00
978-7-121-12332-0 1 59.00
978-7-121-12570-6 20 46.00

store_three.txt:

978-7-121-20038-0 10 100.0
978-0-553-21393-8 1 6.99
978-0-87779-855-2 2 6.99
978-7-121-12332-0 5 65.00
978-7-121-12332-0 1 59.00
978-7-121-12570-6 20 46.00
978-7-04-026845-4 50 60.00

Ответы

▲ 1Принят

Сразу: я не разбирался, верно ли работает ваш код.

Я только о том, откуда ошибка в

auto found = equal_range(store_it->cbegin(), store_it->cend(), book, compare_isbn);

Какой параметр передается в equal_range третьим? Константная ссылка на объект типа, в вашем случае — Sales_data. А что передаете вы? string.

Компилятор и рад бы выполнить преобразование, но вы же сами написали:

explicit Sales_data(const std::string& s)

Еще раз: explicit. Т.е. никакого неявного преобразования!

Вот и вся причина. Ну, сделайте тогда преобразование сами, явно...

auto found = equal_range(store_it->cbegin(), store_it->cend(),
                         Sales_data(book), compare_isbn);

Да, и весь код следует давать прямо в вопросе.