Я хотел бы использовать немутантные алгоритмы из <algorithm>
и алгоритмы увеличения диапазона для набора значений, известных во время компиляции. Я хочу знать, какой подход будет наиболее эффективным (с точки зрения производительности и памяти), исключая подход с использованием переключателей.
Давайте рассмотрим enum (класс или нет) с некоторыми значениями.
enum Enum
{
One,
Two,
Three
};
Рассмотрим тривиальную функцию bool isOneOrTwo(Enum e)
.
Используя подход <algorithm>
, я знаю, что это можно записать двумя способами:
1. std::initializer_list<T>
bool isOneOrTwo(Enum e)
{
constexpr std::initializer<Enum> oneAndTwo{One, Two};
return std::any_of(std::begin(oneAndTwo),
std::end(oneAndTwo),
[e](auto i){return e == i;});
}
2. std::array<T,N>
У нас есть make_pair
и make_tuple
, но, к сожалению, у нас нет функции make_array<T>(T&&..)
, поэтому я написал одну:
template<typename... T>
constexpr auto make_array(T&&... args)
{
return std::array<typename std::common_type<T...>::type, sizeof...(T)>{{std::forward<T>(args)...}};
}
Тогда функцию можно выполнить следующим образом:
bool isOneOrTwo(Enum e)
{
constexpr auto oneAndTwo = make_array(One, Two);
return std::any_of(std::begin(oneAndTwo),
std::end(oneAndTwo),
[e](auto i){return e == i;});
}
Какой из них лучше (std::initializer_list<T>
или std::array<T,N>
) или есть другой способ сделать это быстрее / дешевле?
И окажет ли это влияние, если я поменяю std::any_of(begin_it, end_it, lambda)
на boost::algorithm::any_of_equal(make_iterator_range(begin_it, end_it), value)
?