0

I'm wondering how to make same type for return value? Consider an example:

auto get_securities_by_mic(const std::string& mic)
{
    auto it = some_map.find(mic);
    // I want to write like this:
    if (it == some_map.end()) return std::views::empty<const Security&>;
    return it->second | std::views::transform([](id)->const Security&{...});
}

But it code cannot be compiled(

I came up with solution:

auto get_securities_by_mic(const std::string& mic)
{
    auto it = some_map.find(mic);
    static const std::vector<std::int64_t> empty;
    auto source = it != some_map.end() ? std::views::all(it->second) : std::views::all(empty);
    return source | std::views::transform([](id) -> const Security&{...});
}

Can I write somehow better?

康桓瑋
  • 33,481
  • 5
  • 40
  • 90
Alexey Subbota
  • 938
  • 6
  • 23

1 Answers1

2

Instead of returning an empty range, you can return an optional to indicate whether a value was found

auto get_securities_by_mic(const std::string& mic)
{
  auto it = some_map.find(mic);
  return it != some_map.end() ?
    std::optional{it->second  | std::views::transform(
                                  [](auto id) -> const Security& { return ...; })} :
    std::nullopt;
}

Then you can use it like this

if (auto opt = get_securities_by_mic("key"); opt)
  for (auto x : *opt);
    use(x);

If you still want to return a range, you can also use an empty span to handle not found cases:

auto get_securities_by_mic(const std::string& mic)
{
  auto it = some_map.find(mic);
  return (it != some_map.end() ? std::span{it->second} :
                                 std::span<const std::int64_t>{})
    | std::views::transform([](auto id) -> const Security& { return ...; });
}
康桓瑋
  • 33,481
  • 5
  • 40
  • 90