ericniebler / stl2

LaTeX and Markdown source for the Ranges TS/STL2 and associated proposals
88 stars 8 forks source link

Is it able to make `view_interface::operator[]` non-template? #643

Closed frederick-vs-ja closed 2 years ago

frederick-vs-ja commented 3 years ago

Currently view_interface::operator[] overloads are specified as below ([view.interface.general]/1):

    template<random_­access_­range R = D>
      constexpr decltype(auto) operator[](range_difference_t<R> n) {
        return ranges::begin(derived())[n];
      }
    template<random_­access_­range R = const D>
      constexpr decltype(auto) operator[](range_difference_t<R> n) const {
        return ranges::begin(derived())[n];
      }

Making these functions templates is a common implementation technique, but IMO it's a bit weird in the standard. Such definitions (unintentionally) allow some weird usages, e.g., some_subrange.operator[]<int[42]>(0).

I tried to submit an LWG issue for this, but Daniel told me my resolution was wrong as it would cause ODR violation when involving incomplete types.

Formerly proposed resolution (abandoned):

Change these function heads to: constexpr decltype(auto) operator[](see below n) requires random_access_range<D> constexpr decltype(auto) operator[](see below n) const requires random_access_range<const D> Add Remarks: see below denotes range_difference_t<D> or range_difference_t<const D> if D or const D satisfies random_access_range respectively, otherwise, it is an unspecified type.

Is it able to make these operator[] overloads non-template without ODR violation?

frederick-vs-ja commented 2 years ago

I feel I was wrong. It may be unsuitable to do so.

JohelEGP commented 2 years ago

It can be done with roundabouts, as with conditionally existing members, for example.

Such definitions (unintentionally) allow some weird usages, e.g., some_subrange.operator[]<int[42]>(0).

That may not be portable due to [constraints], and perhaps SD-8.