linksplatform / linksplatform/Delegates
A better delegate type definition?
Open
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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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