Почему обработка сигналов во время ввода останавливает std :: cin от повторного ввода? - PullRequest
0 голосов
/ 05 апреля 2020

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

код (подробности функции ShowMenu не важны):

#include <iostream>
#include <functional>
#include <csignal>
#include "Originator.h"
#include "CareTaker.h"

void ShowMenu(Originator<std::string>& originator, CareTaker<std::string>& careTaker)
{
    std::cout << std::endl;
    std::cout << "1. save" << std::endl;
    std::cout << "2. restore" << std::endl;
    std::cout << "3. delete until" << std::endl;
    std::cout << "4. cancel." << std::endl;
    std::cout << "5. exit." << std::endl;


    int choise, index;
    std::cin >> choise;

    switch (choise)
    {
    case 1:
        careTaker.AddMemento(originator.CreateMemento());
        break;
    case 2:
        std::cin >> index;
        originator.RestoreMemento(careTaker.GetMemento(index));
        break;
    case 3:
        std::cin >> index;
        careTaker.DeleteUntil(index);
        break;
    case 4:
        return;
    case 5:
        exit(0);
    }
}

int main()
{
    Originator<std::string> originator;
    CareTaker<std::string> careTaker;

    std::function<void(int)> func = [&originator, &careTaker](int) {
        return ShowMenu(originator, careTaker); 
    };

    void (*HandleSignal)(int) = func.target<void(int)>();

    std::cout << HandleSignal << std::endl;

    signal(SIGINT, HandleSignal);

    while (true)
    {
        std::cout << "> ";
        std::string text;
        std::cin >> text;

        originator.SetData(text);
        std::cout << "Text : " << originator.GetData() << std::endl << std::endl;
    }
}

Originator, CareTaker и Memento не имеют отношения к проблеме, поэтому я не буду публиковать их код (без необходимости).

В этом коде есть некоторые проблемы:

1 - я хочу получить указатель на функцию void, которая принимает в качестве параметра int для передачи его в функцию signal. Я подошел к нему с помощью лямбды и сохранил ее в std::function. Затем получить указатель от этого std::function. Но по какой-то причине я получаю нулевой указатель. В чем здесь проблема? и как получить указатель на функцию из лямбда-выражения и из std::function?

2 - даже если я позволю originator и careTaker быть глобальными переменными и удалить параметры из функции ShowMenu и передать функцию ShowMenu в функцию signal, l oop продолжает выполнять итерации и не принимает никакого ввода, как если бы я не записывал строку, которая принимает ввод. Почему std::cin не работает нормально?

...