栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

模板相关内容笔记

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

模板相关内容笔记

模板相关内容笔记 一、模板泛化编程 (一)函数模板 1、函数模板定义方式:
template 
Type min(const Type (&r_array)[size])
{
    Type min_val = r_array[0];
    for (int i = 1; i < size; ++i)
    {
        if (r_array[i] < min_val)
        {
            min_val = r_array[i];
        }
    }
    return min_val;
}
2、模板参数

模板参数可以是一个模板类型参数,代表一种类型;可以是一个模板非类型参数,代表一个常量表达式 ;也可以是其他模板。

特殊说明:

  1. 在函数模板定义中声明的对象或类型不能与模板参数同名 ;
  2. 模板类型参数名可以被用来指定函数模板的返回值类型;
  3. 模板参数名在同一模板参数表中只能被使用一次 ,但可以在多个函数模板声明或定义之间被重复使用 ;
  4. 一个模板的定义和多个声明所使用的模板参数名无需相同;
// 三个 min() 的声明都指向同一个函数模板
// 模板的前向声明
template  T min(T, T);
template  U min(U, U);

// 模板的真正定义
template 
Type min(Type a, Type b) {  }  
3、函数模板实例化:
template 
Type min(Type (&p_array)[size]) {  }

// pf 指向 int min( int (&)[10] )
int (*pf)(int (&)[10]) = &min;

typedef int (&rai)[10];
typedef double (&rad)[20];
void func(int (*)(rai));
void func(double (*)(rad));

void main() 
{
    func(&min);
}
  1. 函数模板在它被调用或取其地址时被实例化 ;
  2. 当函数模板被调用时,对函数实参类型的检查决定了模板实参的类型和值;
  3. 模板实参推演期间决定模板实参的类型时,编译器不考虑函数模板实例的返回类型;
  4. 左值转换(从左值到右值的转换、从数组到指针的转换、从函数到指针的转换)、限定修饰符转换和到一个基类(该基类根据一个类模板实例化而来)的转换 ;
  5. 多个函数实参可以参加同一个模板实参的推演过程 如果模板参数在函数参数表中出现多次,则每个推演出来的类型都必须与根据模板实参推演出来的第一个类型完全匹配 ;
  6. 定义一个普通函数,返回类型和**【参数表】**与另一个从模板实例化的函数的相同,调用时,普通函数优先,若只有声明没有定义,则链接失败;
(二)类模板 (三)trait和其他技巧 1、traits——Effective C++ 条款47
template
struct TypeSet{};

template<>
struct TypeSet
{
    typedef Container vector;
    typedef Dlg CDialogFile;
};

template<>
struct TypeSet
{
    typedef Container set;
    typedef Dlg CDialogFont;
};

template
void Fun()
{
    TypeSet::Dlg* pDlg = new TypeSet::Dlg();
    TypeSet::Container ctn();
    
    /// .........
}


/// 静态表示类型信息
/// 非traits
struct Foo
{
    enum {Type = 0};
};

struct Bar
{
    enum {Type = 1};
}

template
void Fun()
{
    if (T::Type == 0)
        /// ......
    else
        /// .....
}


/// traits——1
template
struct Traits
{
    enum { T_Type = T::Type };
};

template<>
struct Traits
{
    enum { Type = 0 };
}

template
void Fun()
{
    if (Traits::Type == 0)
        /// ......
    else
        /// .....
}

/// traits——2
struct Foo_tag{};
struct Int_tag{};

template
struct Traits{};

template<>
struct Traits
{
    typedef Int_tag TraitTag;
};

template<>
struct Traits
{
    typedef Foo_tag TraitTag;
}


template
void Fun(const T& t)
{
    doFun(t);
}

void doFun(const Int_tag&);
void doFun(const Foo_tag&);
2、静态断言
template 
struct static_assert_test;

template <>
struct static_assert_test
{
    enum { value = 1 };
};

template struct static_assert_v{};

template
struct is_same
{
    enum {value = false};
};

template
struct is_same
{
    enum {value = true};
};


#define TYPE_STATIC_ASSERT static_assert_typedef##__COUNTER__

#define static_assert(B) 
    typedef static_assert_v< sizeof( static_assert_test<(bool)(B)> ) > TYPE_STATIC_ASSERT

template
void Fun(const T& t)
{
    /// 只允许int、double 实例化模板
    static_assert( (is_same::value || is_same::value) );
    /// ....
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/931973.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号