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

auto const view not const #618

Closed
h-2 opened this issue Mar 28, 2017 · 3 comments
Closed

auto const view not const #618

h-2 opened this issue Mar 28, 2017 · 3 comments

Comments

@h-2
Copy link
Contributor

h-2 commented Mar 28, 2017

It seems to me that a const view doesn't actually prevent one from modifying the underlying container. I have read through #385 but I am not sure if it's the same issue.

Take this example:

#include <string>
#include <iostream>

#include <range/v3/all.hpp>

int main()
{
    std::string foo{"abcdefgeherefwweed"};
    auto bar = foo | ranges::view::drop(3) | ranges::view::take(4);
    bar[0] = 'X';
    std::cout << foo << '\n'; // "abcXefgeherefwweed"
}

I would expect that changing auto bar = ... to auto const bar = ... would prevent bar from being written to, but this is not the case. OTOH when using ranges::any_random_access_view<char &> instead of auto it works, i.e. const does prevent the element assignment.
From my perspective the explicit cast gives the correct behaviour, maybe something is wrong with the automatic type deduction?

On a related note, do any of the following behave differently:

ranges::any_random_access_view<char &> const
ranges::any_random_access_view<char const &>
ranges::any_random_access_view<char const &> const

?

Thanks for your help!

@CaseyCarter
Copy link
Collaborator

Views have pointer-like semantics: applying const to the type of a view/pointer doesn't mean "I can't modify the values of the elements this view/pointer denotes" it means "I cannot modify the value of this view/pointer such that it denotes different element(s)." #385 is about a different problem: some view types have non-const operations that don't modify the set of elements the view denotes, but must be non-const because they mutate internal state.

If you want a pointer that cannot be used to modify the elements it denotes, you have to apply const to the element type. Similarly, for views you can obtain a view that cannot be used to modify the elements it denotes by composing a given view with view::const_:

#include <string>
#include <iostream>

#include <range/v3/all.hpp>

int main()
{
    std::string foo{"abcdefgeherefwweed"};
    auto bar = foo | ranges::view::drop(3) | ranges::view::take(4) | ranges::view::const_;
    bar[0] = 'X'; // Error
    std::cout << foo << '\n'; // "abcXefgeherefwweed"
}

OTOH when using ranges::any_random_access_view<char &> instead of auto it works, i.e. const does prevent the element assignment.

This sounds like a bug.

do any of the following behave differently

Yes: the reference type of any_XXX_view<char &> is char&, so you can modify the characters it denotes. The reference type of any_XXX_view<char const &> is char const&,so the denoted characters cannot be modified. any_XXX_view<char &> is convertible to any_XXX_view<char const &>, but the reverse is not true.

An any_XXX_view<T> const has a reference type of T, it's unaffected by the const on the view. const on the view type means it cannot be modified after construction to type erase a different view.

@h-2
Copy link
Contributor Author

h-2 commented Mar 28, 2017

Thanks for the long reply! I'll investigate this further tomorrow!

@ericniebler
Copy link
Owner

OTOH when using ranges::any_random_access_view<char &> instead of auto it works, i.e. const does prevent the element assignment.

This sounds like a bug.

Not a bug. view::any is not const-iterable because it could be used to erase the type of a view that is also not const-iterable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants