Я перебираю последовательность аргументов во время компиляции и хочу проверить, может ли один из аргументов быть диапазоном. Если да, то я займусь промежуточными вещами.
template<typename... Args, std::size_t... Indices>
inline auto SomeClass::resolve_args(std::index_sequence<Indices...>) const
{
std::tuple<std::decay_t<Args>...> retval;
size_t i = 0;
size_t f = 0;
([&] {
if constexpr (std::is_integral_v<Args>) {
std::get<Indices>(retval) = sysarg<Args>(i++);
}
else if constexpr (std::is_floating_point_v<Args>)
std::get<Indices>(retval) = sysarg<Args>(f++);
else if constexpr (std::is_same_v<Args, std::basic_string_view<char>>) {
std::get<Indices>(retval) = sysarg<Args>(i); i+= 2;
}
else if constexpr (is_stdstring<Args>::value)
std::get<Indices>(retval) = sysarg<Args>(i++);
else if constexpr (std::is_standard_layout_v<remove_cvref<Args>> && std::is_trivial_v<remove_cvref<Args>>)
std::get<Indices>(retval) = sysarg<Args>(i++);
else
static_assert(always_false<Args>, "Unknown type");
}(), ...);
return retval;
}
Где-то там мне нужно проверить, является ли Args Span. Это возможно? Моя проблема до сих пор заключается в том, что мои попытки создания ветки if constexpr приводят к сбою других комбинаций типов. Итак, выкладываю всю функцию (с небольшими изменениями). Вы можете реализовать sysarg как ничего не делающую функцию.
В идеале подтип span должен быть тривиальным и стандартным_макетом, но я могу разобраться с деталями. Мне просто нужно придумать, как действовать!
К вашему сведению, эта функция работает как положено. Вы путаете Args снаружи лямбда-складки с тем, что внутри.
Кстати, принятый ответ в дубликате не подойдет для std::span.
В этом случае я бы не использовал if constexpr, а использовал бы разрешение перегрузки. В любом случае, что должно произойти, когда есть std::span? Что это значит do span-things?





#include <span>
#include <type_traits>
template <typename T>
struct is_span : std::false_type{};
template <typename T>
struct is_span<std::span<T>> : std::true_type{};
template <typename T>
constexpr bool is_span_v = is_span<T>::value;
int main() {
static_assert(is_span_v<std::span<int>>);
static_assert(!is_span_v<int>);
}
Редактировать:
Вышеупомянутое работает только для диапазонов с динамическим экстентом. Чтобы это работало на всех промежутках, измените специализацию is_span на это:
template <typename T, std::size_t Extent>
struct is_span<std::span<T, Extent>> : std::true_type{};
живой пример
Не правда ли std::span<int, 6>span?
@康桓瑋: Верно. Это соответствует только интервалам std::dynamic_extent.
@康桓瑋 Да, я немного поспешил с ответом. Обновил его.
«Мне нужно проверить, является ли Args диапазоном...» Это невозможно, поскольку
Args— это пакет параметров. Вы не можете сравнивать пакет параметров с типом класса, так же как мы не можем сравнивать1kgс1km. Возможно, вы имели в виду, что хотите проверить, соответствует ли один из аргументов/внутриArgsstd::span<T>, как написано в начале вашего сообщения.