有关C++模版

来源:互联网 发布:小内存win10平板优化 编辑:程序博客网 时间:2024/06/06 05:36

前面看老罗文章时看到里面有很多的模版,不是很了解,这里做个笔记

typedef  类型 定义名;

类型说明只定义了一个数据类型的新名字而不是定义一种新的数据类型。定义名表示这个类型的新名字。
例如: 用下面语句定义整型数的新名字:
typedef int SIGNED_INT;

typedef函数指针用法
typedef  返回类型(*新类型)(参数表)


typedef char (*PTRFUN)(int); PTRFUN pFun; char glFun(int a){ return;} void main() {     pFun = glFun;     (*pFun)(2); } 

然后 我们看下 http://blog.csdn.net/luoshengyang/article/details/46747797 这篇文章里面的一些模版

我们看这个

void MyFunc(int i, const std::string& str) {}  base::Callback<void(const std::string&)> cb = base::Bind(&MyFunc, 23);  cb.Run("hello world"); 
这里我们先看base::Bind 它有两个参数,对应到

template <typename Functor, typename P1>base::Callback<    typename internal::BindState<        typename internal::FunctorTraits<Functor>::RunnableType,        typename internal::FunctorTraits<Functor>::RunType,        void(typename internal::CallbackParamTraits<P1>::StorageType)>            ::UnboundRunType>Bind(Functor functor, const P1& p1) {  // Typedefs for how to store and run the functor.  typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;  typedef typename internal::FunctorTraits<Functor>::RunType RunType;  // Use RunnableType::RunType instead of RunType above because our  // checks should below for bound references need to know what the actual  // functor is going to interpret the argument as.  typedef internal::FunctionTraits<typename RunnableType::RunType>      BoundFunctorTraits;  // Do not allow binding a non-const reference parameter. Non-const reference  // parameters are disallowed by the Google style guide.  Also, binding a  // non-const reference parameter can make for subtle bugs because the  // invoked function will receive a reference to the stored copy of the  // argument and not the original.  COMPILE_ASSERT(      !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ),      do_not_bind_functions_with_nonconst_ref);  // For methods, we need to be careful for parameter 1.  We do not require  // a scoped_refptr because BindState<> itself takes care of AddRef() for  // methods. We also disallow binding of an array as the method's target  // object.  COMPILE_ASSERT(      internal::HasIsMethodTag<RunnableType>::value ||          !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,      p1_is_refcounted_type_and_needs_scoped_refptr);  COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||                     !is_array<P1>::value,                 first_bound_argument_to_method_cannot_be_array);  typedef internal::BindState<RunnableType, RunType,      void(typename internal::CallbackParamTraits<P1>::StorageType)> BindState;  return Callback<typename BindState::UnboundRunType>(      new BindState(internal::MakeRunnable(functor), p1));}

这里的Bind

Functor和P1都是一个类型,P1对应这里就是一个int

而Functor这里对应就是函数的原型void(*)(int, const std::string&)

我们继续看下Bind里面FunctorTraits的定义

// FunctorTraits<>//// See description at top of file.template <typename T>struct FunctorTraits {  typedef RunnableAdapter<T> RunnableType;  typedef typename RunnableType::RunType RunType;};
这里T对应就是前面的Functor,也就是函数原型void(*)(int, const std::string&),这里又用typedef个给RunnableAdapter<T>定义了一个新名字RunnableType

我们看下RunnableAdapter<T>的定义,由于T是void(*)(int, const std::string&),我们把它替换进去RunnableAdapter<void(*)(int, const std::string&)>,所以它对应的是

// Function: Arity 2.template <typename R, typename A1, typename A2>class RunnableAdapter<R(*)(A1, A2)> { public:  typedef R (RunType)(A1, A2);  explicit RunnableAdapter(R(*function)(A1, A2))      : function_(function) {  }  R Run(typename CallbackParamTraits<A1>::ForwardType a1,      typename CallbackParamTraits<A2>::ForwardType a2) {    return function_(CallbackForward(a1), CallbackForward(a2));  } private:  R (*function_)(A1, A2);};
这里R是void,A1是int,A2是const std::string
这里RunnableAdapter

typedef R (RunType)(A1, A2);

定义了一种RunType类型,它返回void,并且有两个参数int  const std::string 正好描述的是上述的FunctorTraits模板参数T,即void(*)(int, const std::string&)。
再看下这里的CallbackForward

template <typename T, bool is_move_only = IsMoveOnlyType<T>::value>struct CallbackParamTraits {  typedef const T& ForwardType;  typedef T StorageType;};
这里T是A1,也就是int 

CallbackParamTraits<P1>::ForwardType的是一个类型为int&的参数,而CallbackParamTraits<P1>::StorageType描述的是一个类型为int的参数。


Bind里面最终调用

  return Callback<typename BindState::UnboundRunType>(      new BindState(internal::MakeRunnable(functor), p1));

作为返回值,这里的p1是我们绑定的一个参数的值23,类型P1是int

先看

template <typename T>typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) {  return RunnableAdapter<T>(t);}
这里的T是functor对应就是函数的原型void(*)(int, const std::string&),即RunnableAdapter<R(*)(A1,A2)> ,t对应函数的地址,也就是前面的MyFunc的地址就保存在其成员变量function_中。

所以这里的BindState对应

 new BindState(RunnableAdapter<R(*)(A1,A2)>, p1);
BindState构造函数含有两个参数,对应到

template <typename Runnable, typename RunType, typename P1>struct BindState<Runnable, RunType, void(P1)> : public BindStateBase {  typedef Runnable RunnableType;  typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;  typedef Invoker<1, BindState, RunType> InvokerType;  typedef typename InvokerType::UnboundRunType UnboundRunType;  // Convenience typedefs for bound argument types.  typedef UnwrapTraits<P1> Bound1UnwrapTraits;  BindState(const Runnable& runnable, const P1& p1)      : runnable_(runnable),        p1_(p1) {    MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);  }  virtual ~BindState() {    MaybeRefcount<HasIsMethodTag<Runnable>::value,      P1>::Release(p1_);  }  RunnableType runnable_;  P1 p1_;};
第一个模板参数Runnable的类型为RunnableAdapter<R(*)(A1, A2)>,这里的R、A1和A2即分别为void、int和const std::string&

第二个模版参数RunType类型为R(*)(A1,A2)

第三个模板数数P1的类型为int,置为p1

p1保存到p1_,runnable保存到runnable_

这里我们看下

  typedef Invoker<1, BindState, RunType> InvokerType;

这里RunType类型为R(*)(A1,A2)所以对应Invoker

// Arity 2 -> 1.template <typename StorageType, typename R,typename X1, typename X2>struct Invoker<1, StorageType, R(X1, X2)> {  typedef R(RunType)(BindStateBase*,      typename CallbackParamTraits<X2>::ForwardType);  typedef R(UnboundRunType)(X2);  static R Run(BindStateBase* base,      typename CallbackParamTraits<X2>::ForwardType x2) {    StorageType* storage = static_cast<StorageType*>(base);    // Local references to make debugger stepping easier. If in a debugger,    // you really want to warp ahead and step through the    // InvokeHelper<>::MakeItSo() call below.    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;    typename Bound1UnwrapTraits::ForwardType x1 =        Bound1UnwrapTraits::Unwrap(storage->p1_);    return InvokeHelper<StorageType::IsWeakCall::value, R,           typename StorageType::RunnableType,           void(typename Bound1UnwrapTraits::ForwardType,               typename CallbackParamTraits<X2>::ForwardType x2)>               ::MakeItSo(storage->runnable_, CallbackForward(x1),                   CallbackForward(x2));  }};
UnboundRunType描述的是一个参数类型为X2的函数,其中,X2是模板类Invoker<1, BindState, RunType>的模板参数,定义为const std::string&。这里UnboundRunType

也就是后面我们调用这个绑定了参数的函数的原型,因为已经有一个参数绑定了,这里调用的时候就只需要后面一个

再看看前面

  return Callback<typename BindState::UnboundRunType>(      new BindState(internal::MakeRunnable(functor), p1));
所以这里Callback的模版typename BindState::UnboundRunType就是void(const std::string&),传给构造函数的参数是new BindState(internal::MakeRunnable(functor), p1) 一个BindState

再看下Run

template <typename R, typename A1>class Callback<R(A1)> : public internal::CallbackBase { public:  typedef R(RunType)(A1);  Callback() : CallbackBase(NULL) { }  // Note that this constructor CANNOT be explicit, and that Bind() CANNOT  // return the exact Callback<> type.  See base/bind.h for details.  template <typename Runnable, typename BindRunType, typename BoundArgsType>  Callback(internal::BindState<Runnable, BindRunType,           BoundArgsType>* bind_state)      : CallbackBase(bind_state) {    // Force the assignment to a local variable of PolymorphicInvoke    // so the compiler will typecheck that the passed in Run() method has    // the correct type.    PolymorphicInvoke invoke_func =        &internal::BindState<Runnable, BindRunType, BoundArgsType>            ::InvokerType::Run;    polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);  }  bool Equals(const Callback& other) const {    return CallbackBase::Equals(other);  }  R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1) const {    PolymorphicInvoke f =        reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);    return f(bind_state_.get(), internal::CallbackForward(a1));  } private:  typedef R(*PolymorphicInvoke)(      internal::BindStateBase*,          typename internal::CallbackParamTraits<A1>::ForwardType);};
这里会把传进来的BindState保存到基类的bind_state

构造函数里面会把BindState的InvokerType的Run转换成InvokeFuncStorage保存到基类的变量polymorphic_invoke_中,InvokerType的Run就是Invoker的Run

  static R Run(BindStateBase* base,      typename CallbackParamTraits<X2>::ForwardType x2) {    StorageType* storage = static_cast<StorageType*>(base);    // Local references to make debugger stepping easier. If in a debugger,    // you really want to warp ahead and step through the    // InvokeHelper<>::MakeItSo() call below.    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;    typename Bound1UnwrapTraits::ForwardType x1 =        Bound1UnwrapTraits::Unwrap(storage->p1_);    return InvokeHelper<StorageType::IsWeakCall::value, R,           typename StorageType::RunnableType,           void(typename Bound1UnwrapTraits::ForwardType,               typename CallbackParamTraits<X2>::ForwardType x2)>               ::MakeItSo(storage->runnable_, CallbackForward(x1),                   CallbackForward(x2));  }


我们看下CallbackBase

class BASE_EXPORT CallbackBase { public:  // Returns true if Callback is null (doesn't refer to anything).  bool is_null() const;  // Returns the Callback into an uninitialized state.  void Reset(); protected:  // In C++, it is safe to cast function pointers to function pointers of  // another type. It is not okay to use void*. We create a InvokeFuncStorage  // that that can store our function pointer, and then cast it back to  // the original type on usage.  typedef void(*InvokeFuncStorage)(void);  // Returns true if this callback equals |other|. |other| may be null.  bool Equals(const CallbackBase& other) const;  // Allow initializing of |bind_state_| via the constructor to avoid default  // initialization of the scoped_refptr.  We do not also initialize  // |polymorphic_invoke_| here because doing a normal assignment in the  // derived Callback templates makes for much nicer compiler errors.  explicit CallbackBase(BindStateBase* bind_state);  // Force the destructor to be instantiated inside this translation unit so  // that our subclasses will not get inlined versions.  Avoids more template  // bloat.  ~CallbackBase();  scoped_refptr<BindStateBase> bind_state_;  InvokeFuncStorage polymorphic_invoke_;};
还有InvokeFuncStorage,是一个函数指针

  typedef void(*InvokeFuncStorage)(void);


我们看Run函数

  R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1) const {    PolymorphicInvoke f =        reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);    return f(bind_state_.get(), internal::CallbackForward(a1));  }


  typedef R(*PolymorphicInvoke)(      internal::BindStateBase*,          typename internal::CallbackParamTraits<A1>::ForwardType);


这跟我们前面保存的Run原型是一致的
然后把bind_state_和新传入的参数一起传给该函数
template <typename StorageType, typename R,typename X1, typename X2>struct Invoker<1, StorageType, R(X1, X2)> {  typedef R(RunType)(BindStateBase*,      typename CallbackParamTraits<X2>::ForwardType);  typedef R(UnboundRunType)(X2);  static R Run(BindStateBase* base,      typename CallbackParamTraits<X2>::ForwardType x2) {    StorageType* storage = static_cast<StorageType*>(base);    // Local references to make debugger stepping easier. If in a debugger,    // you really want to warp ahead and step through the    // InvokeHelper<>::MakeItSo() call below.    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;    typename Bound1UnwrapTraits::ForwardType x1 =        Bound1UnwrapTraits::Unwrap(storage->p1_);    return InvokeHelper<StorageType::IsWeakCall::value, R,           typename StorageType::RunnableType,           void(typename Bound1UnwrapTraits::ForwardType,               typename CallbackParamTraits<X2>::ForwardType x2)>               ::MakeItSo(storage->runnable_, CallbackForward(x1),                   CallbackForward(x2));  }};
这里先获取参数p1_,StorageType是BinderState,前面我们已经把参数p1保存在他里面的p1_,然后调用InvokeHelper的MakeItSo,参数storage->runnable_描述的一个RunnableAdapter<R(*)(A1, A2)>对象的成员函数Run,RunnableAdapter<R(*)(A1, A2)>类的成员变量function_描述的就是前面MyFunc函数的地址,这样就把两个参数都传给该函数了



0 0
原创粉丝点击