Date: Wed, 2 Oct 2024 09:09:12 +0200
That example is potentially ODR breaking as you could have different
compilation units that see different "SomeGlobalFunction":s
// Robin
On Wed, Oct 2, 2024, 08:05 Frederick Virchanza Gotham via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> I respond to Arthur and Thiago in series below.
>
>
> On Tue, Oct 1, 2024 at 4:50 PM Arthur O'Dwyer wrote:
> >
> > Since 'Act' is virtual, we cannot tell what it does with its `args`.
> > For example, it might only care about the arity of the pack:
> > class LightBlueMonkey : public BlueMonkey {
> > int Act(auto&&... args) override { return sizeof...(args); }
> > };
> > or it might care about everything:
> > class DarkBlueMonkey : public BlueMonkey {
> > int Act(auto&&... args) override { (std::cout << ... << args);
> return 0; }
> > };
>
>
> Those two examples don't count. While there are a finite number of
> types to which you can apply "sizeof..." and "cout <<", it isn't a
> small number. In a codebase such as Chromium I think it would be up in
> the thousands.
>
> Let's take a more simple example:
>
> extern int SomeGlobalFunction(char );
> extern bool SomeGlobalFunction(double);
>
> class Frog {
> virtual decltype(auto) Act(auto&&... args) { return
> SomeGlobalFunction( static_cast<decltype(args)>(args)... ); }
> };
>
> When the compiler encounters the above code snippet, it could
> transform the following line:
>
> virtual decltype(auto) Act(auto&&... args) { return
> SomeGlobalFunction( static_cast<decltype(args)>(args)... ); }
>
> into two lines:
>
> virtual int Act(char const arg) { return SomeGlobalFunction(arg); }
> virtual bool Act(double const arg) { return SomeGlobalFunction(arg);
> }
>
> So the rule would be something like:
>
> "A class shall not have a non-static virtual method with the
> parameter list "auto&&... args" unless the inline body of the method
> contains an invocation of a non-template-and-non-variadic function
> with the arguments "static_cast<decltype(args)>(args)..." -- in which
> case the virtual method will be given an instantiation for each of the
> overload signatures of the aforementioned
> non-template-and-non-variadic function."
>
>
> Thiago wrote:
> >>
> >> which means that 'Act' can really only have two possible signatures:
> >>
> >> double Act(int);
> >> int Act(char, char, char);
> >
> > False.
> > You can call Act(0U) thus creating an Act(unsigned)
> > and that unsigned parameter is converted to int upon calling Do().
>
>
> .................which is exactly the same as if you had called "Do"
> giving it an "unsigned" instead of an "int". Hence why 'Act' can be
> restricted to just two signatures.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
compilation units that see different "SomeGlobalFunction":s
// Robin
On Wed, Oct 2, 2024, 08:05 Frederick Virchanza Gotham via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> I respond to Arthur and Thiago in series below.
>
>
> On Tue, Oct 1, 2024 at 4:50 PM Arthur O'Dwyer wrote:
> >
> > Since 'Act' is virtual, we cannot tell what it does with its `args`.
> > For example, it might only care about the arity of the pack:
> > class LightBlueMonkey : public BlueMonkey {
> > int Act(auto&&... args) override { return sizeof...(args); }
> > };
> > or it might care about everything:
> > class DarkBlueMonkey : public BlueMonkey {
> > int Act(auto&&... args) override { (std::cout << ... << args);
> return 0; }
> > };
>
>
> Those two examples don't count. While there are a finite number of
> types to which you can apply "sizeof..." and "cout <<", it isn't a
> small number. In a codebase such as Chromium I think it would be up in
> the thousands.
>
> Let's take a more simple example:
>
> extern int SomeGlobalFunction(char );
> extern bool SomeGlobalFunction(double);
>
> class Frog {
> virtual decltype(auto) Act(auto&&... args) { return
> SomeGlobalFunction( static_cast<decltype(args)>(args)... ); }
> };
>
> When the compiler encounters the above code snippet, it could
> transform the following line:
>
> virtual decltype(auto) Act(auto&&... args) { return
> SomeGlobalFunction( static_cast<decltype(args)>(args)... ); }
>
> into two lines:
>
> virtual int Act(char const arg) { return SomeGlobalFunction(arg); }
> virtual bool Act(double const arg) { return SomeGlobalFunction(arg);
> }
>
> So the rule would be something like:
>
> "A class shall not have a non-static virtual method with the
> parameter list "auto&&... args" unless the inline body of the method
> contains an invocation of a non-template-and-non-variadic function
> with the arguments "static_cast<decltype(args)>(args)..." -- in which
> case the virtual method will be given an instantiation for each of the
> overload signatures of the aforementioned
> non-template-and-non-variadic function."
>
>
> Thiago wrote:
> >>
> >> which means that 'Act' can really only have two possible signatures:
> >>
> >> double Act(int);
> >> int Act(char, char, char);
> >
> > False.
> > You can call Act(0U) thus creating an Act(unsigned)
> > and that unsigned parameter is converted to int upon calling Do().
>
>
> .................which is exactly the same as if you had called "Do"
> giving it an "unsigned" instead of an "int". Hence why 'Act' can be
> restricted to just two signatures.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2024-10-02 07:09:26