std::generator has huge problems.
I think what you're asking is, in this example:
auto f(allocator_arg_t, CoolAllocator) -> std::generator<int>
Should CoolAllocator be type-erased (current design) or not (since it's possible to go through coroutine_traits and have CoolAllocator be a template parameter of the promise type and stored directly)?
Because the allocator is type-erased currently, it is possible to have multiple generators in a container that use different underlying allocators.
But note that the current design allows:
auto g() -> std::generator<int&, int, CoolAllocator>;
Which obviates the need for passing extra function parameters, if CoolAllocator is default constructible. Having that seems useful.
2. Overhead for ueslss default type erasure(default behavior) and stack in generator (used only for element_of, which is basically for(auto&& v : gen) co_yield v;
Its just uselss
You pay for what you dont use.
The paper claims otherwise - I'd like to see some support for this claim. How much overhead is there?
3. It is undefined behavior to call begin for std::generator twice. But iteraing not all values in one loop is a very logical action and expected behavior - just keep generating values
Besides, such an error is extremely non-obvious when using ranges or range based for loop.
This is not at all "a very logical action and expected behavior" - far, far from. This sort of stateful iteration is very much not the design of ranges, and has never been. If I see this in code:
print("{}\n", v | views::take(4));
print("{}\n", v | views::take(4));
This had better either print the same (up to) four elements twice, or be undefined behavior. It is not at all logical or expected that it should print eight different elements. If you want to do that, you can just use the iterators directly and keep using the same iterator through multiple loops. This is totally fine, and would be clear to the reader what is going on.
This is why it is undefined behavior to call begin() on any input range multiple times. Because you cannot iterate such a thing multiple times, and the way that most of these things (including generator) must be implemented, precludes any sort of sensible behavior.
4. interface that is very obscure to the user and requires knowledge of implementation to write efficient code
No one will write generator<const T&> foo(); without knowing why it is needed and why it is better for perfmornace
But there are way to write generator without such problems
generator<const T&> is not a "very obscure" interface. If I want to have a generator that yields references to const, that seems to me like a fairly obvious thing to write. Also, in what way is it "better for performance" and what "knowledge of implementation" is needed "to write efficient code"? Some justification for these claims would be nice.
Barry