C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Not quite a template virtual function

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Wed, 2 Oct 2024 07:05:06 +0100
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.

Received on 2024-10-02 06:05:19