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

Параметры функции по умолчанию игнорируются

Для этой упрощенной части кода я получаю следующую ошибку:

ошибка: слишком мало аргументов для функции   std:: cout < F();

int g(int a = 2, int b = 1)
{
    return a + b;
}

template<class Func>
void generic(Func f)
{
    std::cout << f();
}

int main()
{
    generic(g);
}

Я не могу понять причину того, почему параметры по умолчанию f не передаются в функцию generic. Он ведет себя как f не имеет параметров по умолчанию...

Что там не так?

Как правильно перенаправить параметры по умолчанию?

4b9b3361

Ответ 1

g могут иметь аргументы по умолчанию, но тип &g все еще int(*)(int, int), который не является типом, который можно вызвать без аргументов. В generic мы не можем отличить это - мы уже потеряли контекст аргументов по умолчанию.

Вы можете просто обернуть g в лямбда, чтобы сохранить контекст:

generic([]{ return g(); });

Ответ 2

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

int g(int a=0,int b=0){return 0;}

typedef int (*F1)(int);

int main() {
    F1 x = g;
}

error: cannot initialize a variable of type 'F1' (aka 'int (*)(int)') with
an lvalue of type 'int (int, int)': different number of parameters (1 vs 2)
    F1 x = g;
       ^   ~

Даже с параметрами по умолчанию тип g по-прежнему

int (*) (int,int)

и то, что выводится при создании шаблона.

Если по какой-то причине вы не можете использовать С++ 11 или более поздней версии (т.е. нет lambdas, см. ответ Barry), и вы не против небольшого шаблона, тогда вы можете использовать объект функции:

#include <iostream>

struct g_functor {
    int operator()(int a=0,int b=0){ return a;}
};

template <typename T> void foo(T t) { t(); }

int main() { foo(g_functor()); }

Обратите внимание, что вам нужно создать экземпляр g_functor, чтобы передать его как параметр.