C++模板解读

    xiaoxiao2021-11-28  44

    模板就把他当成:我们定义一个模板,他用来表示类型,函数或者类<>跟的是指定类型

    类型就是比如 int ,long,char,类,结构体等

    模板的主要目的:同一个类,函数可以调用不同类型的参数。 

    #pragma once #include <type_traits>

    //FUNCTOR_TYPEDEF这个宏就相当于:

    //FUNCTOR_TYPEDEF(name, 类型一, 类型二) ========typedef Functor<rettype, 类型一, 类型二> name

    意思就是定义一个class Functor的类型,名叫name(就好比: typedef unsigned int u32;),为class Functor注入模块<rettype, 类型一, 类型二>。。模块对应的定义是在template <class RetType, class... Args>//----------------------------------------------------------------<模板一>

    #define FUNCTOR_TYPEDEF(name, rettype, ...) \     typedef Functor<rettype, ## __VA_ARGS__> name

    //定义一个对象

    #define FUNCTOR_DECLARE(name, rettype, ...) \

        Functor<rettype, ## __VA_ARGS__> name

    //Functor<rettype, ## __VA_ARGS__>::bind<std::remove_reference<decltype(*obj)>::type, func>(obj)

    //其实里面的尖括号可以先去掉,Functor::bind(obj)其实就是调用的类Functor里面的bind静态函数。

    //因为bind也是有模板的(对应--------------------------------------------<模板二>),所以也用<>来带入类型。

    //decltype获得变量的类型,

    //std::remove_reference为C++0x标准库中的元函数,其功能为去除类型中的引用。 //std::remove_reference<U&>::type <=> U //std::remove_reference<U&&>::type <=> U //std::remove_reference<U>::type <=> U

    #define FUNCTOR_BIND(obj, func, rettype, ...) \

        Functor<rettype, ## __VA_ARGS__>::bind<std::remove_reference<decltype(*obj)>::type, func>(obj) #define FUNCTOR_BIND_MEMBER(func, rettype, ...) \     Functor<rettype, ## __VA_ARGS__>::bind<std::remove_reference<decltype(*this)>::type, func>(this) template <class RetType, class... Args>//----------------------------------------------------------------<模板一> class Functor { public:     constexpr Functor(void *obj, RetType (*method)(void *obj, Args...))         : _obj(obj)         , _method(method)     {     }     // Allow to construct an empty Functor     constexpr Functor(decltype(nullptr))         : Functor(nullptr, nullptr) { }     constexpr Functor()         : Functor(nullptr, nullptr) { }     // Call the method on the obj this Functor is bound to     RetType operator()(Args... args) const     {         return _method(_obj, args...);     }     // Compare if the two Functors are calling the same method in the same     // object     inline bool operator==(const Functor<RetType, Args...>& rhs)     {         return _obj == rhs._obj && _method == rhs._method;     }     // Allow to check if there's a method set in the Functor     explicit operator bool() const     {         return _method != nullptr;     } // T::*method表示method必须是类型T里面定义的函数,要调用class里面的函数需要这样定义。     template<class T, RetType ( T::*method)(Args...)>//----------------------------------------------------------------<模板二>     static constexpr Functor bind( T *obj)

        {

    //这里就是返回一个Functor类型的对象。对象不就是_obj,和method_wrapper函数组成嘛。对应3333那两个参数。

            return { obj, method_wrapper<T, method> };     } private:     void *_obj;//------------------------------------------------------------------------------------------------------3333     RetType (*_method)(void *obj, Args...);

        template<class T, RetType (T::*method)(Args...)>//----------------------------------------------------------------(模板三)

    //这里才是真正的调用对象注册的方法。

        static RetType method_wrapper(void *obj, Args... args)//     {         T *t = static_cast<T*>(obj);         return (t->*method)(args...);     } };

    编写模板类:

    模版本身并不是个定义,当实体化的时候才完成了定义,然后拿这个定义才能去建立对象, 所以放的一起

    1.模板类的定义与实现只写在头文件中

    目前主流编译器不支持分离编译,即模板声明写到h文件中,实现写到cpp文件中。 C++标准倒是规定有分离编译,不过对于编译器来说实现比较困难所以大多数编译器不支持(包括vc全系列)

    2.如果要将实现写在cpp中需要:

    template <typename T> bool Vector3<T>::is_inf(void) const {     return isinf(x) || isinf(y) || isinf(z); } template bool Vector3<float>::is_inf(void) const; 对其进行实例化。很麻烦

    3.如果模板声明写到h文件中,实现写到cpp文件中。会出现在生成执行文件时,找不到该函数声明"undefined reference to"

    转载请注明原文地址: https://ju.6miu.com/read-678576.html

    最新回复(0)