Prime number sieve using ranges::view::ints
It may well be more efficient to compute std::sqrt(max) once upfront than to multiply n * n every time around the loop.

Removing an element by value from the set is O(log n), where n is the set size at the time.  This will likely make this method slower than writing to elements in a fixed-size storage (such as a std::vector that's never resized), and creating the return set from that.  Also, find() is much slower than vector lookup.

I think we can probably test m * n &lt;= max instead of the more expensive m &lt;= max / n, if we can arrange that the multiplication doesn't overflow.  It will be fine if 2 * n &lt; std::numeric_limits&lt;number_t&gt;::max() - max.  Also, no need to start at 2 * n when removing - we can start at n * n instead, as all the lower multiples have already been removed due to their smaller factor(s).

And a tiny improvement to the test code - we can stream a single character '\n' to output rather than the string "\n".