Выдается ошибка при вызове функции front() в шаблоне очереди с++

199
07 февраля 2020, 13:20

Я делаю очередь с помощью шаблона . Добавляю туда элементы в виде структур, однако при вызове функции front() (которая должна выводить первую добавленную структуру) выводит ошибку:

error: cannot bind'std::basic_ostream' lvalue to 'std::basic_ostream&&'

Код:

#include <iostream>
#include <queue>   // подключаем заголовочный файл очереди
#include <string>  // заголовочный файл для работы
                   // со строками типа string using namespace std;
struct Deb {
    int age;
    char FIO[20];
    char group[20];
};
int main()
{
    setlocale(LC_ALL, "rus");
    Deb rer;
    queue<Deb> chek;
    int a;
    cout << "Введите количество елементво в очереди - ";
    cin >> a;
    for (int i = 0; i < a; i++) {
        cout << "Введитое возраст:  " << endl;
    t:
        cin >> rer.age;
        if (rer.age >= 80 || rer.age <= 16) {
            cout << "Некоректно введенный возраст. Введите еще 
                раз : " << endl;
                      goto t;
        }
        cout << "Введитое вашу фамилию:  " << endl;
        cin >> rer.FIO;
        cout << "Введитое вашу группу:  " << endl;
        cin >> rer.group;
        chek.push(rer);
    }
    cout << "    " << chek.size() << endl;
    cout << "     " << chek.front() << endl;
    return 0;
}
Answer 1

Метод front возвращает ссылку на первый элемент в очереди. В Вашем случае это будет ссылка на объект класса Deb:

auto& first = check.front(); // first имеет тип Deb&

Далее, Вам необходимо перегрузить оператор << для типа Deb:

std::ostream& operator<<(std::ostream& stream, const Deb& d) { 
    return stream << d.age << " " 
                  << d.FIO << " " 
                  << d.group; 
}

Как справедливо заметил @AnT - Deb - пользовательский тип, в стандартной библиотеке для него нет перегруженного оператора <<, а это значит, что Вы должны реализовать его самостоятельно.

Answer 2

Проблема заключается в том, что функция-член класса front возвращает ссылку типа Deb & на элемент очереди, имеющий тип std::queue<Deb>. Однако оператор operator << не определен для потока std::ostream и объекта структуры Deb. Поэтому компилятор не знает, что делать в этом случае, и выдает сообщение об ошибке.

Самый простой способ обойти проблему - это сначала создать объект на основе возвращаемой ссылки из функции-члена класса front, а затем вывести на консоль члены этого объекта, так как они объявлены управлением доступом public (по умолчанию для структур).

Например,

#include <iostream>
#include <queue>
struct Deb 
{
    int age;
    char FIO[20];
    char group[20];
};
int main()
{
    std::queue<Deb> chek;
    Deb deb1 = { 20, "Maks Boll", "C++" };
    chek.push( deb1 );
    Deb deb2 = chek.front();
    std::cout << "age: " << deb2.age << ", FIO: " << deb2.FIO << ", group: " << deb2.group << '\n';
}

Вывод программы на консоль:

age: 20, FIO: Maks Boll, group: C++

Если вы используете компилятор, который поддерживает C++ 17, то вы можете использовать так называемое структурно связанное объявление (structured binding declaration).

Ниже приведена демонстрационная программа, которая показывает, как можно использовать такое объявление для вывода элементов структуры на консоль.

#include <iostream>
#include <queue>
struct Deb 
{
    int age;
    char FIO[20];
    char group[20];
};
int main()
{
    std::queue<Deb> chek;
    Deb deb = { 20,"Maks Boll", "C++" };
    chek.push( deb );
    const auto [ age, FIO, group] = chek.front();
    std::cout << "age: " << age << ", FIO: " << FIO << ", group: " << group << '\n';
}

Вывод программы:

age: 20, FIO: Maks Boll, group: C++

Кстати сказать, в C++ 17 также определена обобщенная функция std;:size, которую можно использовать со стандартными контейнерами и массивами. Поэтому вы также можете написать

#include <utility>
// ...
std::cout << "    " << std::size( chek ) << '\n';

вместо

cout << "    " << chek.size() << endl;

что делает программы более гибкой и стойкой к изменениям.

В противном случае, если компилятор не поддерживает стандарт C++ 17, вам самостоятельно следует определить такой оператор. К примеру, он может выглядеть следующим образом

std::ostream & operator <<( std::ostream &os, const Deb &deb )
{
    return os << "age: " << deb.age << ", FIO: " << deb.FIO << ", group: " << deb.group;
}

Ниже приведена соответствующая демонстрационная программа.

#include <iostream>
#include <queue>
struct Deb 
{
    int age;
    char FIO[20];
    char group[20];
};
std::ostream & operator <<( std::ostream &os, const Deb &deb )
{
    return os << "age: " << deb.age << ", FIO: " << deb.FIO << ", group: " << deb.group;
}
int main()
{
    std::queue<Deb> chek;
    Deb deb = { 20,"Maks Boll", "C++" };
    chek.push( deb );
    std::cout << chek.front() << '\n';;
}

Ее вывод на консоль идентичен выводу, показанному для предыдущей демонстрационной программы:

age: 20, FIO: Maks Boll, group: C++
READ ALSO
Поймать конец скролла на JQuery

Поймать конец скролла на JQuery

Если запустить ниже код, будет видно что производится автоматический скролл в конец объектаКогда пользователь скроллит вверх до объекта...

284
Прикрепить элемент к стенке браузера

Прикрепить элемент к стенке браузера

Необходимо прикрепить элемент к стенке браузера, чтобы тот взаимодействовал(шапка спускалась) вместе с прокруткой страницы внизНО, при этом...

241
Не распознает шрифт в Safaris

Не распознает шрифт в Safaris

Проблема в том, что проверяя свою верстку на iPhone, шрифты различаются с Android и WindowsКак это исправить?

217
Как на html страницы сделать &ldquo;карту&rdquo; и мини-карту

Как на html страницы сделать “карту” и мини-карту

Вообщем есть html страницаУ нее задний фон это некое изображение

218