linksplatform / linksplatform/Delegates

A better delegate type definition?

Open
#27 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
C++
Stars
4
Forks
3
PR merge metrics
No merged PRs in 30d

Description

#include <iostream>
#include <memory>
#include <concepts>
#include <functional>

struct Object
{
    void Method(const char *str) 
    {
        std::cout << "Object::Method(" << str << ")" << std::endl;
    }
};

// For diagnostics
template <typename M>
struct PointerType {
    // template <typename C, typename T>
    // static T get_member_type(T C::*v);

    template <typename TClass, typename TReturn, typename TArg>
    static TClass get_class_type(TReturn (TClass::*func)(TArg));

    template <typename TClass, typename TReturn, typename TArg>
    static TReturn get_return_type(TReturn (TClass::*func)(TArg));

    template <typename TClass, typename TReturn, typename...TArg>
    static std::tuple<TArg...> get_argument_types(TReturn (TClass::*func)(TArg...));

    typedef decltype(get_class_type(static_cast<M>(nullptr))) class_type;
    typedef decltype(get_return_type(static_cast<M>(nullptr))) return_type;
    typedef decltype(get_argument_types(static_cast<M>(nullptr))) argument_types;
};

template <auto method>
class Delegate
{
    using TClass = typename PointerType<decltype(method)>::class_type;
    using TReturnType = typename PointerType<decltype(method)>::return_type;
    using TArgsTuple = typename PointerType<decltype(method)>::argument_types;

    std::shared_ptr<TClass> object;

public:
    Delegate(std::shared_ptr<TClass> object) : object(std::move(object)) { }

    template<typename ...TArgs>
    requires std::same_as<TArgsTuple, std::tuple<TArgs...>>
    TReturnType operator()(TArgs... args)
    {
        return (*object.*method)(std::forward<decltype(args)>(args)...);
    }
};

auto x = [](const char *str)
{
    std::cout << "Setter::Set(" << str << ")" << std::endl;
};

struct Setter : std::enable_shared_from_this<Setter>
{
    void Set(const char *str)
    {
        std::cout << "Setter::Set(" << str << ")" << std::endl;
    }
};

struct SetterExtender
{
    std::shared_ptr<Setter> setter = std::make_shared<Setter>();

    Delegate<&Setter::Set> Set = setter;
};

// template<typename T>
void call(auto&& delegate)
{
    delegate("calling delegate passed to funciton");
}

int main()
{
    Delegate<&Object::Method> x(std::make_shared<Object>());

    x("call from main");

    SetterExtender se1;

    se1.Set("call from main 1");

    call(se1.Set);

    call([&](const char *str){ se1.Set(str); });

    std::cout << typeid(PointerType<decltype(&Object::Method)>::class_type).name() << std::endl;
    std::cout << typeid(PointerType<decltype(&Object::Method)>::return_type).name() << std::endl;
    std::cout << typeid(PointerType<decltype(&Object::Method)>::argument_types).name() << std::endl;
}

https://godbolt.org/z/a4v1n6GK8

It is possible to pass a pointer to the function into the template.

Maybe we can make it useful somehow?

What if instead of

Delegate<void(const char *)> memberMethod(std::make_shared<Object>(), &Object::Method);

We could write something like this:

Delegate<&Object::Method> memberMethod(std::make_shared<Object>());

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the C++ example in the issue and the linked Compiler Explorer snippet to understand the proposed Delegate template and its diagnostics. The issue does not name repository files or tests; done would require an agreed API direction and a concrete demonstration that the proposed delegate form is useful.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
developer-experience
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.