C++ Logo

std-proposals

Advanced search

Re: call (invoke) member function or static member function of a class in generic context.

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Mon, 25 May 2020 10:43:16 -0400
On Mon, May 25, 2020 at 9:54 AM Nikolay Mihaylov via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> You are correct, this was my first implementation. I think "constexpr if"
> is not very readable and I usually prefer tag dispatch.
>
> About the arguments - yes, those are different types, but [...]
>

The problem is: Because `&A::f` and `&B::f` are both of type `int(*)(int)`,
it is physically impossible to write any function that accepts `&A::f` and
rejects `&B::f`.

struct A { static int f(int); };
struct B { static int f(int); };
int g(int);
int main() {
    A a;
    class_invoke(&A::f, a, 1); // If this is OK...
    class_invoke(&B::f, b, 1); // ...then this must also be OK...
    class_invoke(g, b, 1); // ...and so must this.
}

It would be interesting to explore how the Ranges library (new in C++20)
deals with this "problem." My guess is that they deal with it the same way
as std::invoke does; that is, they don't care about static methods.



> suppose the class is passed from somewhere, here is my real code:
>
> template<class PROTOCOL, class DB_ADAPTER, class CONNECTION>
>> class KeyValueWorkerProcessor{
>> // ...
>> template<typename F>
>> WorkerStatus do_accumulate_(F func){
>> const auto &p = protocol_.getParams();
>> if (p.size() != 4)
>> return err_BadRequest_();
>> const auto &key = p[1];
>> uint16_t const count = from_string<uint16_t>(p[2]);
>> const auto &prefix = p[3];
>> protocol_.response_strings(buffer_, *class_invoke(db_, func,
>> key, count, prefix)* );
>>
>
Looks good to me. Garrett provided you with a nice short 8-line
implementation of `class_invoke`.

Current implementation works and looks very nice and clear, isn't it?
>

Yep. Add Garrett's 8-liner to your codebase and ship it!

–Arthur

Received on 2020-05-25 09:47:19