Как написать обёртку обобщённой функции с помощью шаблонов с переменными числами - PullRequest
1 голос
/ 27 октября 2019

Я только начал баловать себя продвинутым использованием шаблонов. Я пытаюсь написать обобщенную оболочку для функций, чтобы обернуть функции, которые могут вызвать исключения. Если исключений не произошло, функция-обертка должна записать фактическое возвращаемое значение в некоторую ссылку, а затем вернуть true. Если возникла исключительная ситуация, возвращается только false.

Код

#include <string>
#include <iostream>
#include <functional>
#include <exception>
#include <iomanip>

template<typename TReturn, typename ... TArgs>
bool Try(std::function<TReturn(TArgs...)> &function, typename std::function<TReturn(TArgs...)>::result_type& res, TArgs&...args) {
    try {
        res = function(std::forward<TArgs>(args)...);

        return true;
    }
    catch (...) {
        return false;
    }
}

std::string foo(int val) {
    if (val == 0) {
        throw std::exception();
    }

    return "result";
}

int main() {
    std::string res = "noResult";

    //Should be "false=>noResult"
    std::cout << std::boolalpha << Try(foo, res, 0) << "=>" << res;

    //Should be "true=>result"
    std::cout << std::boolalpha << Try(foo, res, 1) << "=>" << res;
}

Ожидания

Я ожидал создания экземпляра шаблона, например bool Try(std::function<std::string(int)>& function, std::string& res, int&arg);

ВместоОн даже не компилируется:

Ошибки:

ни один экземпляр шаблона функции "Try" не соответствует списку аргументов

и

'bool Try (std :: function <_Ret (_Types ...)>, std :: function <_Ret (_Types ...)> :: result_type &, TArgs & ...)': моглине выводить аргумент шаблона для 'std :: function <_Ret (_Types ...)>' из 'std :: string (int)'

Я думаю, способ, которым я вызываю Try, мог бы такжеиметь недостатки.


Я нашел этот простой вопрос , но я не могу заставить его работать с типом возврата.

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


Чего мне не хватает и как это можно сделать? Заранее спасибо!

1 Ответ

2 голосов
/ 27 октября 2019

Почему так много std::function?

template<typename TReturn, typename ... TArgs>
bool Try(TReturn (&function)(TArgs...), TReturn& res, TArgs...args) {
    try {
        res = function(std::forward<TArgs>(args)...);

        return true;
    }
    catch (...) {
        return false;
    }
}

Также вы не можете передавать аргументы типа 0 в качестве ссылки TArgs&.... Просто передайте их такими, какие они есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...