C++ Logo

std-proposals

Advanced search

Re: [std-proposals] New attribute to add implicit using statements for template parameter lists

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Mon, 28 Nov 2022 12:09:05 -0500
On Mon, Nov 28, 2022 at 11:58 AM Ryan Klaus via Std-Proposals <
std-proposals_at_[hidden]> wrote:

>
> Correct me if I'm wrong, but don't the current disambiguation rules for
> using statements cover this?
> These conflicts could occur with using statements already allowed in the
> language.
> Here's an example:
>
> enum class ColorComponents {
> RGBA = 7
> };
>
> enum class ColorComponents2 {
> RGBA = 42
> };
>
> struct RGBA {};
> int main () {
> using enum ColorComponents;
> //using enum ColorComponents2;
> // ^ compilation error
>
> //static constexpr ColorComponents RGBA = ColorComponents(42);
> // ^ compilation error
>
> struct RGBA x; // Removing "struct" makes this ambiguous
> auto y = (struct RGBA){}; // Removing "struct" makes this ambiguous
> ColorComponents z = RGBA; // Okay
>
> return (int)RGBA + (int)z;
> }
>
>
> Attempting to use two enums that have the same enumerator name results in
> a compile error, and theoretically my proposal would work in the same
> fashion as this makes no sense. Similarly, types can either be
> disambiguated through a variety of means or, when not properly
> disambiguated, throw a compile error. Again, theoretically my proposal
> would work in this way.
>

Perhaps, but you'd have to actually come up with the rules that make it
work "that way."
I infer that you're thinking of a rule something like "For each non-type
template parameter of enumeration type, look up all names within the
template argument as if they were in a scope preceded by `using enum
*the-enum-type*`." But then you still have problems with overloaded
templates, where you *don't know* whether a given parameter is of
enumeration type or not:

    template<ColorComponentLayout, ColorComponents> void f(); // #1
    enum NumberOfBalloons { _99, _8888, _777777 };
    template<ColorComponentLayout, NumberOfBalloons> void f(); // #2
    int main() {
        f<RGBA, _8888>(); // Ambiguous? or unambiguously a call to f #2
with NumberOfBalloons::_8888?
    }

And you have new problems — or at least possibilities-for-confusion
("veridical paradoxes") — with things like:

    enum class E { A,B,C,D,E,F,G };
    template<E> struct S {};
    S<A> s; // proposed OK, means S<E::A>
    S<(E)-A> s; // proposed OK, means S<(E::E)-E::A>, *not* S<(E)-E::A>
i.e. S<E(0)>

Modifying the name lookup rules is one of the scariest things you can do
in C++-proposal-land.

–Arthur

Received on 2022-11-28 17:09:18