Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
using T1 = typename TypeAt<0u, Arguments...>::Type;
using T1 = typename TypeAt<1u, Arguments...>::Type;
new (Storage.data()) Callable(std::move(Fn));
#include <tuple>
#include <memory>
#include <cassert>
namespace detail {
template <typename T>
struct call_type : call_type<decltype(&T::operator())>
{};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) volatile > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const volatile > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) &> : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const & > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) volatile & > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const volatile & > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) && > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const && > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) volatile && > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const volatile && > : call_type<ResultType(Args...)> {};
template <typename ResultType, typename ... Args>
struct call_type<ResultType(*)(Args...)> : call_type<ResultType(Args...)> {};
template <typename ResultType, typename ... Args>
struct call_type<ResultType(&)(Args...)> : call_type<ResultType(Args...)> {};
template <typename ResultType, typename ... Args>
struct call_type<ResultType(Args...)>
{
using type = ResultType(Args...);
};
template <class R, class ... Args>
struct any_function {
virtual ~any_function() {};
virtual R invoke(Args ... args)=0;
virtual std::unique_ptr<any_function<R,Args...>> clone() const = 0;
};
template <class F, class R, class ... Args>
struct concrete_function : any_function<R, Args...> {
template <class Q>
concrete_function(Q&& f)
: f_(std::forward<Q>(f))
{};
R invoke(Args ... args) override {
return f_(std::forward<Args>(args)...);
}
std::unique_ptr<any_function<R,Args...>> clone() const override {
return std::make_unique<concrete_function<F,R,Args...>>(f_);
}
private:
F f_;
};
}
template <class Function>
struct function;
template <class R, class ... Args>
struct function<R(Args...)> {
using self_type = function<R(Args...)>;
using result_type = R;
using argument_types = std::tuple<Args...>;
function() {};
function(self_type&& other)
: ptr(std::move(other.ptr))
{}
function(const self_type& other)
: ptr(other.clone())
{}
self_type& operator=(const self_type& other) {
ptr = other.clone();
return *this;
}
self_type& operator=(self_type&& other) {
ptr = std::move(other.ptr);
return *this;
}
template <class F>
function(F&& f)
: ptr(std::make_unique<detail::concrete_function<F,R,Args...>>(std::forward<F>(f)))
{}
R operator()(Args ... args) {
assert(ptr);
return ptr->invoke(std::forward<Args>(args)...);
}
private:
std::unique_ptr<detail::any_function<R,Args...>> clone() const {
if(ptr) {
return ptr->clone();
} else {
return nullptr;
}
}
std::unique_ptr<detail::any_function<R,Args...>> ptr;
};
template<class F>
decltype(auto) make_function(F&& f) {
return function<typename detail::call_type<F>::type>(std::forward<F>(f));
}
template <typename T> struct call_type : call_type<decltype(&T::operator())> {};
struct A { void operator () () const { ; } }; A const a{}; auto f = make_function(a);
#include <tuple>
#include <memory>
#include <cassert>
namespace detail {
template <typename T>
struct call_type : call_type<decltype(&T::operator())>
{};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) volatile > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const volatile > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) &> : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const & > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) volatile & > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const volatile & > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) && > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const && > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) volatile && > : call_type<ResultType(Args...)> {};
template <typename ClassType, typename ResultType, typename ... Args>
struct call_type<ResultType(ClassType::*)(Args...) const volatile && > : call_type<ResultType(Args...)> {};
template <typename ResultType, typename ... Args>
struct call_type<ResultType(*)(Args...)> : call_type<ResultType(Args...)> {};
template <typename ResultType, typename ... Args>
struct call_type<ResultType(&)(Args...)> : call_type<ResultType(Args...)> {};
template <typename ResultType, typename ... Args>
struct call_type<ResultType(Args...)>
{
using type = ResultType(Args...);
};
template <typename T>
struct remove_reference {
using type = T;
};
template <typename ResultType, typename ... Args>
struct remove_reference<ResultType(&)(Args...)> {
using type = ResultType(&)(Args...);
};
template <typename T>
struct remove_reference <T&> {
using type = T;
};
template <class R, class ... Args>
struct any_function {
virtual ~any_function() {};
virtual R invoke(Args ... args)=0;
virtual std::unique_ptr<any_function<R,Args...>> clone() const = 0;
};
template <class F, class R, class ... Args>
struct concrete_function : any_function<R, Args...> {
template <class Q>
concrete_function(Q&& f)
: f_(std::forward<Q>(f))
{};
R invoke(Args ... args) override {
return f_(std::forward<Args>(args)...);
}
std::unique_ptr<any_function<R,Args...>> clone() const override {
return std::make_unique<concrete_function<F,R,Args...>>(f_);
}
private:
F f_;
};
}
template <class Function>
struct function;
template <class R, class ... Args>
struct function<R(Args...)> {
using self_type = function<R(Args...)>;
using result_type = R;
using argument_types = std::tuple<Args...>;
function() {};
function(self_type&& other)
: ptr(std::move(other.ptr))
{}
function(const self_type& other)
: ptr(other.clone())
{}
self_type& operator=(const self_type& other) {
ptr = other.clone();
return *this;
}
self_type& operator=(self_type&& other) {
ptr = std::move(other.ptr);
return *this;
}
template <class F>
function(F&& f)
: ptr(std::make_unique<detail::concrete_function<typename detail::remove_reference<F>::type,R,Args...>>(std::forward<F>(f)))
{}
R operator()(Args ... args) {
assert(ptr);
return ptr->invoke(std::forward<Args>(args)...);
}
private:
std::unique_ptr<detail::any_function<R,Args...>> clone() const {
if(ptr) {
return ptr->clone();
} else {
return nullptr;
}
}
std::unique_ptr<detail::any_function<R,Args...>> ptr;
};
template<class F>
decltype(auto) make_function(F&& f) {
return function<typename detail::call_type<typename detail::remove_reference<F>::type>::type>(std::forward<F>(f));
}
template <typename T>
struct call_type : call_type<decltype(&std::remove_reference_t< T >::operator())>
{};
// Какой должна быть сигнатура функции, принимающей такой аргумент? someOtherFunction(Lambda);
void someOtherFunction(decltype(Lambda) lam);
Один мой знакомый подкинул мне интересную задачку: нужно вызвать функцию через указатель и передать в нее предварительно сохраненные аргументы. Обязательным условием было не использовать std::function.
вызвать функцию через указатель и передать в нее предварительно сохраненные аргументы
#include <utility> template< typename ...types > auto make_caller(types &&... _values) { return [_values...] (auto && callee) mutable -> decltype(auto) { return std::forward< decltype(callee) >(callee)(std::forward< types >(_values)...); }; } // main.cpp #include <iostream> #include <cstdlib> struct A { template< typename ...types > void operator () (types...) const & { std::cout << __PRETTY_FUNCTION__ << std::endl; } template< typename ...types > void operator () (types...) && { std::cout << __PRETTY_FUNCTION__ << std::endl; } }; void f(int, float, double, long double) { std::cout << __PRETTY_FUNCTION__ << std::endl; } int main() { auto caller = make_caller(1, 1.0f, 1.0, 1.0L); caller(A{}); A const a{}; caller(a); caller(f); caller(&f); // в точности то, что нужно return EXIT_SUCCESS; }
Передача сохраненных аргументов в функцию