Как вызвать стандартный функциональный аргумент шаблона в C ++? - PullRequest
3 голосов
/ 16 февраля 2020

Я хочу, чтобы моя шаблонная функция

template<class function>
int probe(function call = [] (int a, int b) { return a+b; })
{
    return call(10, 10);
}

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

#include <iostream>
#include <string>

template<class function>
int probe(function call = [] (int a, int b) { return a+b; })
{
    return call(10, 10);
}

int main()
{
    std::cout << probe([](int a,int b){ return a-b;});
}

Программа выводит то, что я ожидал: ноль. Однако я явно обозначил для этого вызова, какую функцию я передаю - я имею в виду это лямбда-выражение в скобках [](int a,int b){ return a-b;}. Это нормально, пока я ничего не передаю - вызов std::cout << probe(); неверен, однако я ожидал, что функция будет использовать функцию по умолчанию function call = [] (int a, int b) { return a+b; }. Итак, как мне вызвать функцию, что экземпляр этой функции будет использовать лямбда-выражение по умолчанию в объявлении?

Ответы [ 2 ]

6 голосов
/ 16 февраля 2020

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

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

template<class function>
int probe(function call)
{
    return call(10, 10);
}

inline int probe() 
{ 
     return probe([] (int a, int b) { return a+b; }); 
}
2 голосов
/ 16 февраля 2020

Другим способом может быть добавление значения по умолчанию для параметра шаблона.

Очевидно, что тип должен быть совместим со значением по умолчанию для call (decltype([] (int a, int b) { return a+b; }) не работает, потому что каждый раз, когда вы определяете лямбду это другой объект).

template <typename function = std::function<int(int,int)>>
int probe (function call = [] (int a, int b) { return a+b; })
{
    return call(10, 10);
}

Теперь

probe();

работает, если вы помните #include <functional>.

В противном случае вы можете определить значение по умолчанию для call, сохраните его в константе, чтобы вы могли использовать decltype() (и не нужно #include <functional>)

static const auto lam = [] (int a, int b) { return a+b; };

template <typename function = decltype(lam)>
int probe (function call = lam)
{
    return call(10, 10);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...