Доступ к пакету параметров C вне диапазона

#c #templates #parameter-pack

#c #шаблоны #пакет параметров

Вопрос:

Я немного новичок в parameter pack, и я столкнулся с проблемой, связанной с индексом вне диапазона. Чтобы упростить проблему, я хочу получить доступ к n-му элементу (скажем, 3-му) в пакете параметров внутри функции. Если вызов функции не передает 3 параметра (или более), верните nullptr. Может быть, есть рекурсивное решение, позволяющее безопасно игнорировать случай меньшего количества параметров?

 template <int I, class... Ts>
decltype(auto) get_element(Tsamp;amp;... ts) {
    return std::get<I>(std::forward_as_tuple(ts...));
}

    template <typename... Args>
    void foo(Args ... args)
    {
        auto p = get_element<3>(args...);
    }


int main()
{
    int a = 1;
    foo(a);
    return 0;
}
 

Ошибка C2338 индекс кортежа выходит за пределы
Ошибка C2672 ‘std::get’: не найдена соответствующая перегруженная функция

Комментарии:

1. foo должен быть вызван как минимум с 3 параметрами. Вы только что предоставили 1.

2. @Красный. Волна Пожалуйста, внимательно прочтите вопрос! ногудатит полностью осознает это.

Ответ №1:

Попробуйте это (начиная с C 17)

 template <int I, class... Ts>
  decltype(auto) get_element(Tsamp;amp;... ts) {
  if constexpr (I < sizeof...(Ts))
    return std::get<I>(std::forward_as_tuple(ts...));
  else
    return nullptr;
}
 

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

Также имейте в виду, что std::get основан на нуле! Итак, для рабочего примера вам нужно не три, а как минимум четыре параметра.

Комментарии:

1. Для предложенного кода я получаю ошибку C2181: недопустимое else без сопоставления if

2. Какой компилятор вы используете? Поддерживает ли он C 17?

3. Похоже, у меня нет поддержки C 17 (ЭТО виновато) — использование VS2015 _MSC_VER: 1900 _MSC_FULL_VER : 190024215 _MSC_BUILD: 1 _MSVC_LANG: C 14

4. Если C 17 в настоящее время не подходит для вас, например, здесь можно использовать мета-счетчик шаблонов.

5. Я пытаюсь использовать Linux с ошибкой gcc версии 7.2.0 (GCC): ‘if constexpr’ доступен только с -std= c 1z или -std= gnu 1z [-Ошибка]