Как я могу устранить неоднозначность многоточия?

Следующий код будет скомпилирован с error: call of overloaded 'f(int)' is ambiguous

Могу ли я решить эту проблему без использования va_list когда я звоню f с одним параметром?


Это для функции printf. Мне просто интересно, смогу ли я повысить эффективность работы с простым делом отдельно, не вводя новое имя.

Есть ли обходной путь?

#include <cstdarg>

void f(int n, ...) {
va_list args;
va_start(args, n);
//Do something
va_end(args);
}

void f(int n) {
//Do something without va_list
}

int main() {
f(42);
return 0;
}

2

Решение

Вы не можете иметь эту перегрузку (явно), так как она всегда будет неоднозначной. Следующие параграфы в стандарте имеют отношение, я думаю:

[Over.match.viable]

1 Из набора функций-кандидатов, построенных для данного контекста
([over.match.funcs]), выбирается набор жизнеспособных функций, из которых
лучшая функция будет выбрана путем сравнения преобразования аргументов
последовательности для лучшего соответствия
([Over.match.best]). Выбор
Жизнеспособные функции учитывают отношения между аргументами и
параметры функции, кроме ранжирования конверсионных последовательностей.

2 Во-первых, чтобы быть жизнеспособной функцией, функция-кандидат должна иметь
Достаточно параметров для согласования по количеству с аргументами в списке.

  • Если в списке m аргументов, все функции-кандидаты, имеющие ровно m параметров, являются жизнеспособными.

  • Функция-кандидат, имеющая менее m параметров, является жизнеспособной, только если она имеет многоточие в своем списке параметров ([dcl.fct]). Для
    цели разрешения перегрузки, любой аргумент, для которого нет
    соответствующий параметр считается «совпадающим с многоточием»
    ([over.ics.ellipsis]).

  • Функция-кандидат, имеющая более m параметров, является жизнеспособной, только если (m + 1) -й параметр имеет аргумент по умолчанию.130 Для целей
    разрешение перегрузки, список параметров усекается справа, поэтому
    что есть ровно m параметров.

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


Возможное решение

Давайте воспользуемся другими правилами перегрузки. Функция шаблона, сгенерированная и найденная в разрешении перегрузки, считается меньшим соответствием, чем функция без шаблона. Итак, давайте сделаем версию многоточия шаблоном:

#include <iostream>
#include <type_traits>
#include <cstdarg>

void vf(int n, std::va_arg args) {
//Do something with args
}

template<typename T>
auto f(T n, ...)
-> std::enable_if_t<std::is_same<T, int>::value> {
std::va_list args;
va_start(args, n);
vf(n, args);
va_end(args);
}

void f(int n) {
//Do something without va_list
}

int main() {
f(42);
f(42, 53);
return 0;
}

Но мы применим SFINAE к возвращаемому типу, поэтому его можно создать только тогда, когда T является целым числом (таким образом, давая вам исходную функцию). Теперь версия с многоточием выбирается только тогда, когда версия с одним параметром больше не является жизнеспособной, то есть когда имеется более одного параметра.

4

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector