This is my understanding of what is happening. It starts from a different angle: type erasure.
std::function<void()>is an example of an erase class type. It accepts the concepts of “calling without arguments and returns nothing” along with the auxiliary concepts of “copy construction” and “destroy” and wraps it in a neat little package.
So you can do
void groot () { std::cout << "I am groot!\n"; }
std::function<void()> f = groot;
f();
and groot. Or we can pass a lambda, or an object to a function, or an expression std::bind, or boost::functionto std::functionand call it.
, : std::function . , , , std::function , . , groot boost::function.
std::function<void()>, , std::function, copy, destroy invoke void().
:
template<class Sig>
struct func_type_eraser;
template<class R, class... Args>
struct func_type_eraser<R(Args...)> {
virtual R operator()(Args...) const = 0;
virtual func_type_eraser* clone() const = 0;
virtual ~func_type_eraser() {};
};
template<class Sig, class T>
struct func_type_eraser_impl;
3 , , .
template<class Sig>
struct function;
template<class R, class... Args>
struct function<R(Args...)> {
std::unique_ptr<func_type_eraser<R(Args...)>> pImpl;
R operator()( Args... args ) const {
return (*pImpl)( std::forward<Args>(args)... );
}
~function() = default;
function(function const& o) : pImpl( o.pImpl ? o.pImpl->clone() : nullptr ) {}
function(function&&) = default;
function(function& o) : function(const_cast<function const&>(o)) {}
function(function const&& o) : function(o) {}
template<class T>
function(T&& t) : pImpl( new func_type_eraser_impl<R(Args...), std::decay_t<T>>{std::forward<T>(t)} )
{}
};
, , , Regular - . (, ), function , int - , ..
- invoke, copy, move, destroy - pImpl ( move, ).
. - function. , , T - , - . ( ++ std::function , ).
...:
template<class R, class... Args, class T>
struct func_type_eraser_impl<R(Args...), T> : func_type_eraser<R(Args...)> {
T t;
virtual R operator()(Args... args) const override {
return t( std::forward<Args>(args)... );
}
virtual func_type_eraser_impl* clone() const override {
return new func_type_eraser_impl{t};
}
virtual ~func_type_eraser_impl() {}
};
... , func_type_eraser T.
4 , 3 , , , 3 .
:
, .
- , std::begin, , ADL ( ).
, ADL.
, - "", " .begin() " " " " " ".
.
, , , . - , ostream << X print(X).
print_it . using impl_namespace::print, a print(t).
impl_namespace::print(X) a cout << X.
. , - , , , , .
. 9 , , , .
. , , , : " , ".
, , " ". , , , , . , , .
, , , - (.. , . , , , ). - , , .
, , . , " ", (), : , , , .
, . , . , , , , . , , , , (O (n) - O (lg ( n)) ). " " .
, . , .