Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[range.istream.view] Remove constexpr-ness? #6757

Open
hewillk opened this issue Jan 5, 2024 · 3 comments
Open

[range.istream.view] Remove constexpr-ness? #6757

hewillk opened this issue Jan 5, 2024 · 3 comments
Labels
lwg Issue must be reviewed by LWG.

Comments

@hewillk
Copy link
Contributor

hewillk commented Jan 5, 2024

As we all know, it is unreasonable to create basic_istream during compile-time. However, the member functions of basic_istream_view are all declared as constexpr. I don’t quite understand why?

If the intention here is to support constexpr basic_istream (which is not unreasonable), then why are almost all the members of basic_istream_view::iterator non-constexpr except for the constructor? I'm confused by such inconsistency.

Would it be more appropriate to remove all constexpr qualifiers from this section (although end() can be constexpr by its implementation)?

Did I miss something?

@frederick-vs-ja
Copy link
Contributor

Would it be more appropriate to remove all constexpr qualifiers from this section (although end() can be constexpr by its implementation)?

I think some or all constexpr specifiers in [range.istream.view] may be unintended. But they don't seem defective and work in some edge cases. Can we find a case where constexpr triggers additional instantiation which can be ill-formed for some incomplete types?

constexpr works even without support for constexpr basic_istream!

The constexpr on the constructor and end definitely make some sense (although not so much). E.g. the following is currently well-formed, and I don't think it make much sense to make it ill-formed.

#include <iostream>
#include <ranges>

constexpr auto sent = std::views::istream<int>(std::cin).end();

The situations where constexpr on begin and the constructor of the iterator work are currently present, despite extremely contrived.

#include <iostream>
#include <ranges>

struct Foo {
    template<class CharT, class Traits>
    friend constexpr std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& is, Foo) {
        return is;
    }
};

static_assert([] {
    auto v = std::views::istream<Foo>(std::cin);
    auto it = v.begin();
    return true;
}());

The status quo is inconsistent as there're non-constexpr functions. It's possibly reasonable to add constexpr to both operator++s and operator*, but not to the operator==.

@hewillk
Copy link
Contributor Author

hewillk commented Jan 5, 2024

But they don't seem defective and work in some edge cases.

Although they can work in some edge cases, these cases are useless and unreasonable in my opinion.
Could you come up with some really meaningful cases?

The constexpr on the constructor and end definitely make some sense (although not so much). E.g. the following is currently well-formed, and I don't think it make much sense to make it ill-formed.

std::generator::end is completely constexpr-able but it doesn't, because coroutine, like istream, is completely a run-time thing. Adding constexpr to it is of debatable value in my opinion.

@jensmaurer
Copy link
Member

This is not an editorial concern, it seems.

@jensmaurer jensmaurer added the lwg Issue must be reviewed by LWG. label Jan 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lwg Issue must be reviewed by LWG.
Projects
None yet
Development

No branches or pull requests

3 participants