вывод аргумента шаблона std :: function - PullRequest
2 голосов
/ 15 января 2020

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

template<typename T, class Iterable>
void foreach1(std::function<void(T&)> action, Iterable& iterable) {
    std::cout << typeid(T).name() << std::endl;
    for (auto& data : iterable)
        action(data);
}

Если я вызываю функцию таким образом:

std::vector<int> a = { 1, 2, 3 };
foreach1([](int& data) {
    std::cout << data << std::endl;
}, a);

Я получаю ошибку. Я знаю, что могу решить эту проблему, заменив std :: function шаблоном следующим образом:

template<class Action, class Iterable>
void foreach2(Action action, Iterable& iterable) {
//std::cout << typeid(T).name() << std::endl; // no access to T
for (auto& data : iterable)
    action(data);
}

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

1 Ответ

3 голосов
/ 15 января 2020

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

Я предлагаю использовать второй параметр:

template<class Action, class Iterable>
void foreach2(Action action, Iterable& iterable)

И для определения T, начните с создания std::function из action:

std::function(action)

Затем напишите шаблон, чтобы получить тип параметра std::function:

template <typename T> struct std_func_param {};
template <typename R, typename T> struct std_func_param<std::function<R(T)>> {using type = T;};
template <typename T> using std_func_param_t = typename std_func_param<T>::type;

Использовать его как это:

using T = std_func_param_t<decltype(std::function(action))>;
...