Reputation: 4747
I have multiple containers with the same element type T
. I would like to select one of the containers depending on a enum.
I tried something like this:
auto range = [category,system]() -> auto {
switch(category) {
case sound_category::voice:
return std::ranges::views::all (system->dialogue_voices); // could be std::array
case sound_category::mono:
return std::ranges::views::all (system->mono_voices); // could be std::vector
case sound_category::music:
return std::ranges::views::all (system->music_voices); // could be std::list
default:
return std::ranges::views::all (system->sfx_voices); // could be std::deque
}
}();
but that will result in a compiler error, since the deduced type in the cases is different.
Is there some way to achieve that?
Upvotes: 2
Views: 260
Reputation: 217283
ranges-v3 has any_view for type erasure view.
So it would be something like:
auto range = [category,system]() -> ranges::v3::any_view<Voice>
{
switch(category) {
case sound_category::voice:
return std::ranges::views::all (system->dialogue_voices); // could be std::array
case sound_category::mono:
return std::ranges::views::all (system->mono_voices); // could be std::vector
case sound_category::music:
return std::ranges::views::all (system->music_voices); // could be std::list
default:
return std::ranges::views::all (system->sfx_voices); // could be std::deque
}
}();
Upvotes: 2
Reputation: 40811
Instead of something like:
auto range = [category,system]() -> auto {
switch(category) {
case sound_category::voice:
// ...
}
}();
// stuff with range
You can use a visitor pattern:
auto visitor = [&](const auto& range) {
// stuff with range
};
switch (category) {
case sound_category::voice:
return visitor(system->dialogue_voices);
case sound_category::mono:
return visitor(system->mono_voices);
// ...
}
Upvotes: 1
Reputation: 141040
Use a subrange from two iterators.
#include <ranges>
#include <array>
int main() {
std::array<int, 2> a;
std::array<int, 3> b;
auto c = std::ranges::subrange<int*>(a.begin(), a.end());
c = std::ranges::subrange<int*>(b.begin(), b.end());
}
Upvotes: 1