‘va_start’ используется в функции с исправленной ошибкой args

Моя функция nullPointcheck:

template<typename T, typename... Args>
bool __nullPointCheck(T first, Args... args)
{
bool ret = true;
va_list vl;
auto n = sizeof...(args);
va_start(vl, n);
for (auto i = 0; i <= n; ++i)
{
auto p = va_arg(vl, T);
if (!p)
{
ret = false;
}
}
va_end(vl);
return ret;
}

но я получаю ошибку сборки ndk следующим образом:

'va_start' used in function with fixed args
va_start(vl, n);

когда я меняю второй параметр в va_start на первый следующим образом:

va_start(vl, first);

ndk-build экспортирует ошибку следующим образом:

     'va_start' used in function with fixed args
va_start(vl, first);
^
E:/ANDROID_HOME/android-ndk-r10c/toolchains/llvm-3.5/prebuilt/windows-x86_64/bin
\..\lib\clang\3.5\include\stdarg.h:33:29: note:
expanded from macro 'va_start'
#define va_start(ap, param) __builtin_va_start(ap, param)

В vs2013 нет ошибок, но код может пройти этап ndk-build

-1

Решение

va_start и т. д. можно использовать только в функции, прототип которой заканчивается ...); , Это отличается от пакета параметров. Ваш код использует пакет параметров. Синтаксис использования пакетов параметров отличается от синтаксиса для функций с переменными числами.

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

inline constexpr bool nullPointCheck() { return true; }

template<typename T, typename... Args>
constexpr bool nullPointCheck(T&& first, Args&&... args)
{
return first && nullPointCheck(args...);
}

Ответ Рентгена тоже хорош.


Вы можете фактически использовать эту функцию, чтобы проверить, является ли любой произвольный список аргументов true, Я использовал универсальные ссылки, чтобы копии не делались из аргументов; это не имеет значения для указателей, но может иметь значение для более сложных типов.

Чтобы ограничить функцию только принятием указателей, измените T&& в T *, (Покидать Args&& как есть). Если вы также хотите принять буквальное nullptr тогда вам тоже нужна перегрузка:

inline constexpr bool nullPointCheck(std::nullptr_t) { return false; }

так как nullptr на самом деле не выводит ни к какому T *,

3

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

Мое решение, которое может пройти этап компиляции, таково:

template<typename T, typename... Params, std::size_t N = sizeof...(Params)>
static bool nullPointCheck(Params... params)
{
std::array<T, N> arr = { params... };
for (auto point : arr)
{
if (!point)
{
return false;
}
}
return true;
}
1

По вопросам рекламы [email protected]