问题描述
你知道,我们可以将lambda函数包装或存储到 $ float(float,float)在C ++中新的有效表达式
它使用一些。
template< typename T&
struct function;
template< typename Result,typename ... Args>
struct function< Result(Args ...)> {
private:
//这是将擦除实际类型的位
struct concept {
virtual Result operator()(Args ...)const = 0;
};
//这个模板提供了从`concept`得到的派生类。
//可以存储和调用任何类型的op()
template< typename T>
struct model:concept {
template< typename U>
model(U& u):t(std :: forward< U>(u)){}
result operator
t(std :: forward< Args>(a)...);
}
T t;
};
//这是实际存储
//注意如何不使用`model<?>`类型
std :: unique_ptr< concept> fn;
public:
//构造一个`model< T>`,但将它作为指向`concept`的指针存储
//这是擦除发生
template< typename T,
typename = typename std :: enable_if<
std :: is_convertible<
decltype(t(std :: declval< Args>()...)),
结果
> :: value
> :: type>
function(T& t)
:fn(new model< typename std :: decay< T> :: type>(std :: forward< T> b
$ b //做虚拟调用
结果操作符()(Args ... args)const {
return(* fn)(std :: forward< Args> ...);
}
};
(请注意,为了简单起见,我忽略了几件事:它不能被复制,问题;不要在实际代码中使用此代码)
You know, we can wrap or store a lambda function to a std::function:
#include <iostream> #include <functional> int main() { std::function<float (float, float)> add = [](float a, float b) // ^^^^^^^^^^^^^^^^^^^^ { return a + b; }; std::cout << add(1, 2) << std::endl; }
My question is around std::function, as you can see it is a template class but it can accept any kind of function signature.
For example float (float, float) in this form return_value (first_arg, second_arg).
What's the structure of std::function and how does it accept a function signature like x(y,z) and how it works with it? Is float (float, float) a new valid expression in C++?
It uses some type erasure technique.
One possibility is to use mix subtype polymorphism with templates. Here's a simplified version, just to give a feel for the overall structure:
template <typename T> struct function; template <typename Result, typename... Args> struct function<Result(Args...)> { private: // this is the bit that will erase the actual type struct concept { virtual Result operator()(Args...) const = 0; }; // this template provides us derived classes from `concept` // that can store and invoke op() for any type template <typename T> struct model : concept { template <typename U> model(U&& u) : t(std::forward<U>(u)) {} Result operator()(Args... a) const override { t(std::forward<Args>(a)...); } T t; }; // this is the actual storage // note how the `model<?>` type is not used here std::unique_ptr<concept> fn; public: // construct a `model<T>`, but store it as a pointer to `concept` // this is where the erasure "happens" template <typename T, typename=typename std::enable_if< std::is_convertible< decltype( t(std::declval<Args>()...) ), Result >::value >::type> function(T&& t) : fn(new model<typename std::decay<T>::type>(std::forward<T>(t))) {} // do the virtual call Result operator()(Args... args) const { return (*fn)(std::forward<Args>(args)...); } };
(Note that I overlooked several things for the sake of simplicity: it cannot be copied, and maybe other problems; don't use this code in real code)
这篇关于std :: function的工作原理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!