Параметры функции шаблона Variadic и вывод ссылочного типа

Я упускаю кое-что очень фундаментальное о выводе типов здесь:

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

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

static void val_arg(int)            { }
static void ref_arg(const int&)     { }

template <typename... Args>
static void helper(void (*fun)(Args...), Args... args)
{
    (*fun)(args...);
}

void proxy(const int& arg)
{
    helper(&val_arg, arg);  // Fine
    helper(&ref_arg, arg);  // 'void helper(void (__cdecl *)(Args...),Args...)': template parameter 'Args' is ambiguous
                            // note: could be 'const int&'
                            // note: or       'int'
}

void test()
{
    proxy(1);               // Force 1 to be const int&
}

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


person Jaap    schedule 09.09.2018    source источник


Ответы (1)


Args... не выводит ссылочный тип.

template <typename Fun, typename... Args>
static void helper(Fun fun, Args&&... args)
{
    fun(std::forward<Args>(args)...);
}
person n. 1.8e9-where's-my-share m.    schedule 09.09.2018
comment
Мне потребовалось некоторое время, прежде чем я понял, что вы имели в виду. Я эффективно форсировал подпись функции, явно выполняя int (*) (taArgs ...), что создавало несоответствие между ними и, вероятно, сбивало с толку компилятор. Оставив сигнатуру функции в качестве параметра шаблона, это исчезло. Спасибо! - person Jaap; 09.09.2018