C ++ Выход из функции на ранней стадии - PullRequest
0 голосов
/ 30 июня 2018

У меня два вопроса.

Первый касается работы с функциями. Мне нужно выйти из функции на ранней стадии при условии.

Например:

std::string concat(std::string& x, std::string& y, std::vector<std::string>& vec)
{
    if (atoi(x.c_str()) < 0)
    {
        return;
    }
    else {
        std::string concatStr = y + x;

        top_back(vec);
        top_back(vec);

        return concatStr;
    }
}

Как видите, функция должна возвращать строку, но если строка x (которую я, конечно, преобразую в int) меньше 0, то я теоретически должен выйти из функции.

Проблема с написанием только return; заключается в том, что компилятор говорит мне, что ему нужно вернуть значение.

Второй вопрос: как мне удалить последнюю строку с консоли? Это связано с первым вопросом, поскольку кто-то предположил, что return ""; хороший обходной путь, но он записывает пробел в консоль, что в моем случае с программой, которую я пишу, не очень хорошо и вызывает проблемы.

Ответы [ 2 ]

0 голосов
/ 30 июня 2018

Поскольку вы не удовлетворены решениями C ++ 17, можно написать собственную реализацию std::optional.

template<typename T>
class Optional
{
    bool m_HasValue;
    T m_Object;
public:
    Optional() : m_HasValue(false){};
    Optional(T&& Object) : m_HasValue(true), m_Object(Object){};
    operator T&(){return m_Object;}
    operator bool(){return m_HasValue;}
    T& operator*(){return m_Object;}
};

Это очень упрощенная версия std::optional, но она удовлетворит ваши потребности. Его использование остается таким же, как в этом посте выше .

using std::string;
Optional<string> DoSomething(string Input)
{
    if(Input == "dontprocessme")
        return {}
    // ... otherwise process the string
    string Output;
    // blah blah
    return Output;
}

// ...
auto RetString = DoSomething("processme");
if(RetString)
    std::cout << *RetString;
0 голосов
/ 30 июня 2018

Если вы можете скомпилировать с использованием C ++ 17, вы можете использовать std::optional, чтобы позволить вам при необходимости вернуть что-то из функции. Мы переписали бы вашу функцию на

std::optional<std::string> concat(std::string& x, std::string& y, std::vector<std::string>& vec)
{
    if (atoi(x.c_str()) < 0)
    {
        return {};
    }
    else 
    {
        std::string concatStr = y + x;

        top_back(vec);
        top_back(vec);

        return concatStr;
    }
}

И тогда на сайте вызовов вы можете использовать его как

auto ret =  concat(some, stuff, here)
if(ret) // only print if ret actually holds a string
    std::cout << *ret;

В качестве альтернативы вы можете использовать unique_ptr и возвращать пустой указатель, если результата нет. Функция изменится на

std::unique_ptr<std::string> concat(std::string& x, std::string& y, std::vector<std::string>& vec)
{
    if (atoi(x.c_str()) < 0)
    {
        return {};
    }
    else 
    {
        std::string concatStr = y + x;

        top_back(vec);
        top_back(vec);

        return std::make_unique<std::string>(concatStr);
    }
}

но сайт звонков останется прежним.


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

std::string concat(std::string& x, std::string& y, std::vector<std::string>& vec)
{
    if (atoi(x.c_str()) < 0)
    {
        return {};
    }
    else 
    {
        std::string concatStr = y + x;

        top_back(vec);
        top_back(vec);

        return concatStr;
    }
}


int main()
{
    //...
    auto ret =  concat(some, stuff, here)
    if(ret != "") // only print if ret actually holds a string
        std::cout << ret;
    //...
}
...