精华内容
参与话题
问答
  • 一、函数模板 template.h #pragma once #include <iostream> #include <map> template <typename T> T funcadd(T a, T b) { T addhe = a + b; return addhe; } template <typename T, ...

    一、函数模板

    template.h

    #pragma once
    #include <iostream>
    #include <map>
    
    template <typename T>
    T funcadd(T a, T b)
    {
    	T addhe = a + b;
    	return addhe;
    }
    
    template <typename T, int a, int b=7>
    int funcadd1(T c)
    {
    	int addhe = (int)c + a + b;
    	return addhe;
    }
    
    template <typename T>
    typename T::size_type getLength(const T &c)//typedef int string:size_type,T::size_type是一个类型,所以前面要加上typename
    {
    	if (c.empty())
    		return 0;
    	return c.size();
    }
    
    template <typename T1, typename T2, typename T3>
    T1 sum(T2 i, T3 j)
    {
    	T1 result = i + j;
    	return result;
    }

    main.cpp

    #include <iostream>
    #include "template.h"
    using namespace std;
    int main()
    {
        cout << "Hello World!\n";
    	funcadd(5, 6);
    	funcadd1<int, 5, 6>(7);//必须强行指定类型
    	string mytest = "I love China";
    	string::size_type size = getLength(mytest);
    	sum<int>(22, 33);//必须强行指定类型
    }

    函数模板:默认自行推倒类型,如需要,可强行指定。

     

    二、类模板、类成员函数模板

    template.h

    #pragma once
    #include <iostream>
    #include <map>
    
    template <typename C>
    class A
    {
    public:
    	template <typename T2>
    	A(T2 v1, T2 v2);
    
    	template <typename T>
    	void myft(T tmft);
    };
    
    template <typename C>
    template <typename T2>
    A<C>::A(T2 v1, T2 v2)
    {
    
    }
    
    template <typename C>
    template <typename T>
    void A<C>::myft(T tmft)
    {
    	std::cout << tmft << std::endl;
    }

    main.cpp

    #include <iostream>
    #include "template.h"
    using namespace std;
    int main()
    {
    	A<float> a(1.3f, 1.4f);
    	a.myft(3);
    	return 1;
    }
    

    模板类声明和类定义必须在同一个.h文件中。

    展开全文
  • 成员函数模板

    2016-07-29 10:54:00
    智能指针:必须编写一个成员函数模板。因为我们无法写出所有的智能指针的构造函数,一旦Derived体系有新的补充就又要根据其他智能指针构造自己,实在太多了,根本不能写完。 因为一个template可以被无限量具现化,...

    真实指针支持隐式转换:1)Derived class指针可以隐式转换为Base class指针;2)"指向non-const对象"的指针可以转换成"指向const对象"的指针。

    智能指针:必须编写一个成员函数模板。因为我们无法写出所有的智能指针的构造函数,一旦Derived体系有新的补充就又要根据其他智能指针构造自己,实在太多了,根本不能写完。

    因为一个template可以被无限量具现化,以至于生成无限量函数,所以我们不写构造函数,而是写一个构造模板,称为成员函数模板。

     

    成员函数模板:

    根据自己的理解,我认为成员函数模板其实就是放在class里面的函数模板。

    如果声明member template用于"泛化copy构造"或"泛化assignment操作",你还是需要声明正常的copy构造函数和copy assignment操作符。

    什么叫泛化构造函数呢?

    template<class T>
    
    classshared_ptr{
    
    public:
    
    template<class Y>
    
        explicit shared_ptr(Y* p);
    
    template<class Y>
    
        shared_ptr(shared_ptr<Y> const& r); //泛化copy构造函数
    
    template<class Y>
    
        explicit shared_ptr(weak_ptr<Y> const& r);
    
    template<class Y>
    
        explicit shared_ptr(auto_ptr<Y> const& r);
    
    template<class Y>
    
        shared_ptr& operator=(shared_ptr<Y> const& r); //赋值
    
    template<class Y>
    
        shared_ptr& operator=(auto_ptr<Y> const& r);
    
    ……
    
    };

     

    当T和Y类型一样时,泛化copy构造函数就是普通的copy构造函数了。

    转载于:https://www.cnblogs.com/qiushuixiaozhanshi/p/5717474.html

    展开全文
  • 普通类的成员函数模板 #include <iostream> #include "myvector.hpp" #include "test.h" using namespace std; class A { public: template<typename T> void myft(T temp) //成员函数模板 { ...

    普通类的成员函数模板

    不管是普通类还是类模板,它的成员函数可以是一个函数模板,称为“成员函数模板”,不可以是虚函数,否则编译器会报错。 

    #include <iostream>
    #include "myvector.hpp"
    #include "test.h"
    using namespace std;
    
    class A
    {
    public:
        template<typename T>
        void myft(T temp)    //成员函数模板
        {
            cout << temp <<endl;
        }
    };
       
    int main()
    {
        //普通类的成员函数模板
        //不管是普通类,还是类模板,它的成员函数可以是一个函数模板,称为“成员函数模板”,不可以是虚函数
        
        A a;
        a.myft(3);  //执行这句话的时候,才会实例化这个模板。
    
        cout << "Hello world!" << endl;
        return 0;
    }
    

    类模板的成员函数模板

    #include <iostream>
    #include "myvector.hpp"
    #include "test.h"
    using namespace std;
    
    template<typename C>
    class A
    {
    public:
        template <typename T2>
        A(T2 v1, T2 v2);
       // {
       //构造函数我们也引入自己的模板,和整个类的模板C没关系
       //}
    
        template<typename T>
        void myft(T temp)    //成员函数模板
        {
            cout << temp <<endl;
        }
        void myfunc()  //普通成员函数
        {
    
        }
        C m_ic;
    };
        template <typename C> //先跟类的模板参数列表
        template <typename T2>  //再跟构造函数自己的模板参数列表
        A<C>::A(T2 v1, T2 v2)
        {
            cout << v1 <<" "<<v2<< endl;
        }
    
    int main()
    {
        //类模板的成员函数模板
        //类模板的模板参数必须用<>指定,  成员函数模板(函数模板)的参数都可以推断。
        A<float>  a(1 , 2);
        A<float>  a2(1.2 , 2.2);
    
        //类模板的成员函数(包括普通成员函数、成员函数)只有为程序所用,才进行实例化
        //如果某函数从未使用,则不会实例化该成员函数。
        a.myft(9); //调用的时候才会实例化
    
        cout << "Hello world!" << endl;
        return 0;
    }
    

    类模板的成员函数(包括普通成员函数、成员函数模板)只有为程序所用时(代码中出现了)才会实例化。如果某函数从未使用则不会实例化(.obj 中生成代码)该成员函数。

    (也就是说如果代码中没有调用到类成员函数时,编译器编译生成的 .obj 文件中是没有这个成员函数代码的)

    模板显式实例化,模板声明

    模板实例化,每个cpp文件都会实例化自己的模板。

    为了防止多个.cpp文件中都实例化相同的类模板,所以C++11提出了一个解决方法,我们称为"显式实例化";通过"显式实例化"避免生成多个相同类模板实例的开销。

    模板的实例化定义只有一个,模板的实例化声明可以有多个。

    ca.h

    #pragma once
    #ifndef __CAH__
    #define __CAH__
    
    #include <iostream>
    
    // 类模板的参数
    template <typename C>
    class A // 普通类
    {
    public:
        // 构造函数模板
        // 与整个类的模板没有关系
        template <typename T2>
        A(T2 v1, T2 v2);
    
        template <typename T>
        // 成员函数模板
        void myft(T tmpt)
        {
            cout << tmpt << endl;
        }
    
        // 普通成员函数
        template <typename T2>
        void myfunc(T2 v1, T2 v2);
    
        C m_ic; // 类模板变量
    };
    
    // 先跟类的模板参数列表
    template <typename C>
    // 再跟构造函数自己的模板参数列表
    template <typename T2>
    A<C>::A(T2 v1, T2 v2)
    {
        cout << v1 << v2 << endl;
    }
    
    template <typename T>
    void mfunc123(T v1, T v2)
    {
        cout << v1 + v2 << endl;
    }
    
    #endif

    ca.cpp

    #include "ca.h"
    
    using namespace std;
    
    // 显式实例化手段中的实例化定义,这种实例化只需在一个.cpp
    // 文件中写就可以
    // 编译器遇到这段代码就直接实例化一个A<float>
    template A<float>; 
    
    void mfunc()
    {
        A<float> a(1, 2);
    }
    
    // 先跟类的模板参数列表
    template <typename C>
    // 再跟构造函数自己的模板参数列表
    template <typename T2>
    void A<C>::myfunc(T2 v1, T2 v2)
    {
    
    }
    
    // 编译器会为其生成代码
    template void mfunc123(int v1, int v2);  

    main.cpp

    #include <iostream>
    #include "ca.h"
    
    using namespace std;
    
    // 显式实例化手段中的"实例化声明"
    // 其他所有.cpp文件用到这个类型的话都这么写
    // 在一个文件中实例化,其他文件全部为声明
    // extern template A<float>;
    // extern作用:不会在在本文件中生成一个extern后面所表示的模板的实例化代码
    // extern目的:告诉编译器,在其他的源文件(.cpp)中已经有了一个改该模板的实例化版本了。
    extern template A<float>;
    
    // 显式声明函数模板
    extern template void mfunc123(int v1, int v2);
    
    int main()
    {
        A<float> a(1, 2);
    
        A<float> b(1.1, 2.2);
    
        return 0;
    }
    

    只需要在一个 .cpp 文件中做实例化定义,在其他 .cpp 文件中做实例化声明
    extern template A<float>
    extern作用:不会在本文件中生成一个 extern后边所表示的模板的实例化版本。

    extern目的:高作编译器,在其他的源 .cpp文件 中已经有了一个该模板的实例化版本了。

    (extern实际上可能没有达到我们预期系统所能达到的效果,还是会实例化类模板)

    模板的实例化定义只有一个,实例化声明可以有多个。

    总结:

    vs2017不太推荐这个特色写法。
     

    展开全文
  • 这几天本来想将Lua_Tinker移植到Linux上去的,但是由于VC中的模板写法与gcc中的模板写法有些不同之处,比如下面一段代码: struct pop_ { template<typename T> static T invoke(lua_State *L, int index) { ...
    这几天本来想将Lua_Tinker移植到Linux上去的,但是由于VC中的模板写法与gcc中的模板写法有些不同之处,比如下面一段代码:

    struct pop_
    {
    template<typename T>
    static T invoke(lua_State *L, int index) { return lua2type<T>::invoke(L, index); }
    template<>
    static char* invoke(lua_State *L, int index) { return (char*)lua_tostring(L, index); }
    template<>
    static const char* invoke(lua_State *L, int index) { return (const char*)lua_tostring(L, index); }
    };

    在VS2003中就没有问题,但是在Linux中用g++编译就会出现问题,g++不支持这种写法。因为Lua_Tinker全是模板,而且有很多这种模板与全特化同在一个类或者结构中的模板,而至今(到笔者写稿时为止)也没有找到一种解决方案可以将上面所示代码正确移植到Linux,所以Lua_Tinker向Linux的移植到现在为止还并没有成功!虽然,这次移植并没有成功,但是我还是在这次移植中得到了许多关于模板的写法的经验。下面就介绍一下类模板中的函数模板在类内定义与类外定义的两种写法:
    第一种:类内定义

    // 类内定义写法
    template<typename T>
    class CA
    {
    template<typename RET>
    static RET f()
    {
    RET t;
    return t;
    }
    };

    第二种:类外定义
    // 类外定义的写法
    template<typename T>
    class CA
    {
    template<typename RET>
    static RET f()
    {
    RET t;
    return t;
    }
    };

    template<typename T>
    template<typename RET>
    RET CA<T>::f()
    {
    RET t;
    return t;
    }

    以上两中写法在VC中和g++中都可以顺利地编译!关于文章开头的第一段代码,如何写才能在g++中顺利编译呢?由于g++不支持类模板中函数模板全特化的template<>写法,但支持template<int>,template<char*>等等的全特化写法,所以将文章第一段代码写为如下形式即可在g++中编译通过:
    struct pop_
    {
    template<typename T>
    static T invoke(lua_State *L, int index) { return lua2type<T>::invoke(L, index); }
    template<char*>
    static char* invoke(lua_State *L, int index) { return (char*)lua_tostring(L, index); }
    template<const char*>
    static const char* invoke(lua_State *L, int index) { return (const char*)lua_tostring(L, index); }
    };

    但是,由于g++不支持将void,float,double三种类型作为模板参数,所以template<void>,template<float>,template<double>在g++中编译会出错!

    转载于:https://www.cnblogs.com/black/p/5171749.html

    展开全文
  • https://blog.csdn.net/qaz2549066580/article/details/43988169 #include<iostream> #include<typeinfo> using namespace std; template<typename T> class A{ ... virtual...
  • c++ 模板----成员函数模板

    千次阅读 2019-07-04 17:47:29
    Member Template(成员模板) class member function可以是个template,但这样的member template既...在这里,MyClass::f声明了一个成员函数集,适用于任何类型参数。参数类型为T类型。 相同类型的类模板作为函数参数...
  • 成员函数模板生成“可接受所有兼容类型”的函数。如果想阻止隐式转换,就要写copy构造函数,赋值操作的explicit多态版本。 声明成员函数模板用于泛化copy构造函数,赋值操作时,还是要声明普通copy构造函数,赋值...
  • 45 运用成员函数模板接受所有兼容类型 例子: 注: 如果你声明member templates用于“泛化copy构造”或“泛化assignment操作”,你还是需要声明正常的 copy 构造函数和 copy assignment 操作符。
  • 待续
  • 009成员函数模板与模板显式实例化 #include<iostream> #include<cstdlib> #include<string> #include<vector> using namespace std; class A { public: template <typename T> ...
  • 成员函数模板、显式实例化、声明普通类的成员函数模板类模板的成员函数模板模板显式实例化、模板声明 普通类的成员函数模板 #include<iostream> #include<cstdlib> #include<string> #include<...
  • I have heard that C++ class member function templates can't be virtual. 我听说C ++类成员函数模板不能是虚拟的。 Is th
  • 所谓智能指针是“行为像指针”的对象,并提供指针没有的机能。例如条款13曾经提及std::auto_ptr和tr1::shared_ptr如何能够被用来在正确时机自动删除heap-based资源。STL容器的迭代器几乎总是智能指针;...
  • Effective C++笔记 Use member function templates to accpet “all compatible types” 泛化copy构造函数 ...对成员函数群进行筛除 支持赋值操作 类的copy构造和copy assignment操作符 总结
  • 类模板和成员函数模板并不是类和成员函数定义,它们只是C++编译器指令,仅仅说明了如何生成类和成员函数定义。模板的具体实现被称为实例化。由于模板不是函数,它们不能单都编译,模板必须与特定的模板实例化请求...
  • 条款45:运用成员函数模板接受所有兼容类型 例: template<typename T> class A{ public: template<typename Y> void func1(A<Y>& y1); A(const A& a); //复制构造函数 template<...
  • 1.普通类的成员函数模板 不管是普通类还是模板类,成员函数都可以是函数模板,称为“成员函数模板”,但不可以是虚函数,否则编译器报错。 2.类模板的模板参数必须用<>指定,成员函数模板(函数模板)的模板参数...
  • 文章目录Template和泛型编程——249总结——...我们来构造一个成员函数模板: template<typename T> class SmartPtr{ public: template<typename U> SmartPtr(const SmartPtr<U>& other); ...
  • 1. "智能指针"是行为像指针的对象,但它们能提供指针没有的功能:shared_ptr,weak_ptr,auto_ptr(见条款13)实现对堆内存的自动管理,STL的迭代器实现对整个容器的遍历等. C++内置类型指针(int*,char*等)的优势在于支持...
  • 实例代码: // #include <iostream> #include <... void myft(T tmpt){ //成员函数模板 cout << tmpt << endl; } }; template<typename C> //类的模板参数 class B {
  • 智能指针是行为像指针的对象,真的指针做的很好的事情是:支持隐式转换,派生类指针可以隐式转换为基类指针,指向non-const对象的指针可以转换为指向const对象等等,比如: class Top {...}; class Middle : public ...
  • 普通类的成员函数模板 不管是普通类还是类模板,它的成员函数可以是一个函数模板,称为“成员函数模板”,不可以是虚函数,否则编译器会报错。 class A{ public: template<typename T> void myfunc(T ...
  • 这几天本来想将Lua_Tinker移植到Linux上去的,但是由于VC中的模板写法与gcc中的模板写法有些不同之处,比如下面一段代码:  struct pop_   {  template   static T invoke(lua_State *L,
  • 成员函数模板特化

    2016-12-03 21:19:00
    //类成员函数模板特化 #include &lt;stdio.h&gt; class A{ public: template &lt;class T&gt; void Print(){ printf("A template\n"); } }; template&lt;&gt; void A::Print...

空空如也

1 2 3 4 5 ... 20
收藏数 5,265
精华内容 2,106
关键字:

成员函数模板