Подтвердить что ты не робот

Вычет функции

Скажем, у нас есть такой шаблон:

template<typename F>
class A
{
public:
  template<typename... Args>
  A(F f, Args... args)
  { /* Do something... */ }
};

И теперь я хочу использовать его каким-то образом, как этот:

A<int(int)> a(::close, 1);

Теперь вопрос: есть ли способ опустить <int(int)>, потому что компилятор может знать эту информацию для ::close? Нет необходимости сохранять "дизайн" шаблона.

Что касается конкретной задачи, мне нужно создать шаблон класса. Объекты этого класса могут использовать функцию и параметры для этой функции во время построения и позже вызвать эту функцию.

4b9b3361

Ответ 1

Нет, вы (в настоящее время) не можете. Стандартный способ сделать это - создать функцию "make_like" (например, make_pair, make_optional...):

template<typename F, typename... Args>
A<std::decay_t<F>> make_A (F &&f, Args&&... args) {
    return {std::forward<F>(f), std::forward<Args>(args)...};
}

С++ 17 введет вывод аргументов шаблона для класса, который позволит вам делать именно то, что вы хотите (см. Также ответ Барри ниже).

Ответ 2

Благодаря принятию вывода параметра шаблона для конструкторов в С++ 17 вы сможете просто написать:

A a(::close, 1);

До этого вам просто нужно написать factory, чтобы сделать вывод для вас:

template <class F, class... Args>
A<std::decay_t<F>> make_a(F&& f, Args&&... args) {
    return {std::forward<F>(f), std::forward<Args>(args)...};
}

auto a = make_a(::close, 1);

Это немного подробный, но, по крайней мере, вам не нужно беспокоиться об эффективности - здесь не будет никаких копий благодаря RVO.

Ответ 3

Вы не можете опустить аргументы класса шаблона, если они не дефолты. То, что вы можете сделать, это иметь функцию-производитель, которая выводит аргумент и пересылает этот аргумент классу шаблона, возвращая объект соответствующего экземпляра.

template<typename F, typename... Args>
A<F> make_A(F f, Args&&... args) {
    return A<F>(f, std::forward<Args>(args)...);
}