Reputation: 12283
Given a class
class Foo {
public:
std::shared_ptr<const Bar> quux(const std::string&, std::uint32_t);
}
I can declare an std::function
that has the same interface:
std::function<std::shared_ptr<const Bar>(const std::string&, std::uint32_t)> baz = ...
Is there a way of compressing that declaration such that the template arguments to std::function
are derived from the declaration of that method, something like:
std::function<functype(X::quux)> baz = ...
where functype
is an imaginary C++ operator similar to decltype
. Is there a way to do this / does c++ have such a capability?
I do see that the method has a slightly different signature actually as it would also take a reference/pointer to the this
object; it would be fine for me to derive such a signature too.
Upvotes: 3
Views: 595
Reputation: 2201
Yes, you can. Adapting How do I get the argument types of a function pointer in a variadic template class? to your request, we get:
template<typename T>
struct function_traits;
template<typename R, typename C, typename ...Args>
struct function_traits<R(C::*)(Args...)>
{
using type = std::function<R(Args...)>;
};
class Bar;
class Foo {
public:
std::shared_ptr<const Bar> quux(const std::string&, std::uint32_t);
};
int main()
{
std::cout << std::is_same<
std::function<std::shared_ptr<const Bar>(const std::string&, std::uint32_t)>,
function_traits<decltype(&Foo::quux)>::type>::value << std::endl;
}
To make it work with constant methods you will need another specialization:
template<typename R, typename C, typename ...Args>
struct function_traits<R(C::*)(Args...) const>
{
using type = std::function<R(Args...)>;
};
But you will get problems with overloaded methods, because in order to resolve overloading you will need to specify the arguments anyway.
Upvotes: 6