内容简介:May 13th, 2020The C++ language standard library comes with aThe way this is done is with the assistance of a polymorphic helper object that understands the specific callable it is wrapping.
Inside std::function , part 1: The basic idea
Raymond
May 13th, 2020
The C++ language standard library comes with a std::function template type which represents a “thing you can invoke”. It can hold any callable, such as
operator()
The way this is done is with the assistance of a polymorphic helper object that understands the specific callable it is wrapping.
Here’s a sketch. For concreteness, let’s say we’re implementing std::function<bool(int, char*)> . For readability, I’ve de-uglified¹ the identifiers.
struct callable_base
{
callable_base() = default;
virtual ~callable_base() { }
virtual bool invoke(int, char*) = 0;
virtual unique_ptr<callable_base> clone() = 0;
};
template<typename T>
struct callable : callable_base
{
T m_t;
callable(T const& t) : m_t(t) {}
callable(T&& t) : m_t(move(t)) {}
bool invoke(int a, char* b) override
{
return m_t(a, b);
}
unique_ptr<callable_base> clone() override
{
return make_unique<callable>(m_t);
}
};
struct function
{
std::unique_ptr<callable_base> m_callable;
template<typename T>
function(T&& t) :
m_callable(new callable<decay_t<T>>
(forward<T>(t)))
{
}
function(const function& other) :
m_callable(other.m_callable ?
other.m_callable->clone() : nullptr)
{
}
function(function&& other) = default;
bool operator()(int a, char* b)
{
// TODO: bad_function_call exception
return m_callable->invoke(a, b);
}
};
The idea is that each function has a callable_base , which is an interface that allows us to perform basic operations on callable objects: Create a copy, invoke it, and destroy it. Invoking the function forwards the invoke to the callable_base . Copying the function requires a special clone method on the callable_base , because unique_ptr is not copyable.
Constructing the function is a matter of creating a custom callable for the specific functor. It’s conceptually simple, but the C++ language makes us write out a bunch of stuff to get it to work. We just want a callable that wraps the thing that was passed to the constructor.
The std::function in the standard library is basically like this, but with additional optimizations to avoid an allocation in the case of a small callable . Said optimizations are in fact mandatory by the standard if the callable is a plain function pointer or a reference_wrapper .
We’ll look at that optimization next time, because it gives us some insight into how we can do similar things with our own types.
¹ Uglification is the process of taking readable names and transforming them into names that are reserved for the implemenmtation. Different libraries have different uglification conventions. For the Microsoft Visual C++ implementation of the standard library, the uglifications tend to be
_My _Ty _Fn _P _
以上所述就是小编给大家介绍的《Inside std::function, part 1: The basic idea》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
计算统计
Geof H.Givens、Jennifer A.Hoeting / 王兆军、刘民千、邹长亮、杨建峰 / 人民邮电出版社 / 2009-09-01 / 59.00元
随着计算机的快速发展, 数理统计中许多涉及大计算量的有效方法也得到了广泛应用与迅猛发展, 可以说, 计算统计已是统计中一个很重要的研究方向. 本书既包含一些经典的统计计算方法, 如求解非线性方程组的牛顿方法、传统的随机模拟方法等, 又全面地介绍了近些年来发展起来的某些新方法, 如模拟退火算法、基因算法、EM算法、MCMC方法、Bootstrap方法等, 并通过某些实例, 对这些方法的应用进行......一起来看看 《计算统计》 这本书的介绍吧!