《C++标准库第2版》3.2 虽旧犹新的语言特性 笔记

2023-09-15 15:21:36

3.2 虽旧犹新的语言特性

非类型模板参数

1.除了类型参数之外,我们也可以为template使用nontype paramatter.

2.非类型参数看作是template类型的一部分

bitset<32> flags32;
bitset<50> flags50;
// 这两个看作是两个不同类型的template

模板参数默认值

class template 可以拥有默认参数

function template也可以拥有默认参数

// 类模板
template <typename T1, typename T2 = int>
class TmpClass1 {};

// no default argument for 'T2',感觉有点像函数的默认参数,一个参数有了默认值,那么这个参数后面的参数都必须有默认值
// 通过查阅资料:类模板的默认模板参数从右往左开始指定
// template <typename T1 = double, typename T2>
// class TmpClass2 {};

// 函数模板
// 这两个都能编译通过
template <typename T1 = double, typename T2>
void func(T1 arg1, T2 arg2) {}

template <typename T1, typename T2 = double>
void func1(T1 arg1, T2 arg2) {}

关键字typename

关键值typename用来指明后面紧跟的是个类型

注意事项:C++的一般性规则是,template内的任何标识符都被视为一个value,除非它加上typename

#include <iostream>

class Q
{
public:
    using SubType = int;
};

template <typename T>
class MyClass
{
    // 这样写编译器会直接提示需要在前面加上typename
    // T::SubType *ptr;
    typename T::SubType *ptr;

public:
    MyClass() {}
    ~MyClass() {}
};

int main(int argc, char const *argv[])
{
    /* code */
    MyClass<Q> myclassq;
    return 0;
}

成员模板

class的成员函数可以是一个template。然而member template不可以是virtual

通常用来支持class template内的成员之间的自动类型转化。

#include <iostream>
// 基本用法
class MyClass
{
    public:
        MyClass() {}
        ~MyClass() = default;
    template<typename T>
    void f(T a)
    {
        // 这里面的操作是T这个类型支持的。
        ;//
    }
};

// 常用用法
template<typename T>
class MyClass1 
{
    private:
        T value;
    public:
        template <typename X>
        void assign(const MyClass1<X>&x)
        {
            value = x.getValue();
        }

        T getValue() const 
        {
            return value;
        }
};

void f()
{
    MyClass1<double> d;
    MyClass1<int> i;
    d.assign(d);
    d.assign(i); 
}

// 特殊情况: member template 构造函数
template <typename T>
class MyClass2
{
public:
    // 没有这个会报错:error: no matching function for call to 'MyClass2<double>::MyClass2()'
    MyClass2() {}
    template <typename U>
    MyClass2(const MyClass2<U> &x)
    {
            std::cout << "MyClass(const MyClass<U>&x)" << std::endl;
    }
};

void f1()
{
    MyClass2<double> xd;
    MyClass2<double> xd2(xd);
    MyClass2<int> xi(xd);

    // 输出结果:只有一次MyClass(const MyClass<U>&x)
    // 通过查阅资料:发现当xd2与xd类型相同时,通过隐式生成的copy构造函数完成。类型不同的时候才通过我们写的那个template
}

int main(int argc, char const *argv[])
{
    f();
    f1();
    return 0;
}

嵌套式的class template

template <typename T>
class MyClass
{
	template<typename T2>
	class NestedClass {};
};

3.2.1 基础类型的明确初始化

知识点:

“一个明确的构造函数调用,但不给实参”这样的语法,基础类型会被设定初值0

如果一个template强迫设置初值为0,其值就是所谓的zero initialized,否则就是default initialized

int i1;         // undefined value 
int i2 = int(); // 0
int i3{};       // 0

利用这一个特性

template <typename T>
void f()
{
    T x = T();
    std::cout << x << std::endl;
}

3.2.2 main()定义式

// 这个是我这补全工具自动补全生成的,没有报错。
int main(int argc, char const *argv[])
{
}

// main的合法定义式
int main()
{

}

int main(int argc, char **argv)
{

}

int main(int argc, char *argv[])
{

}
// 通常情况下,会写一个return 0,但是不是必须。
// 可以使用exit()/quick_exit()/terminate()
更多推荐

Python的协程异步IO(asyncio)详解

一、协程简介1.1定义协程不是系统级线程,很多时候协程被称为“轻量级线程”、“微线程”、“纤程(fiber)”等。简单来说可以认为协程是线程里不同的函数,这些函数之间可以相互快速切换。协程和用户态线程非常接近,用户态线程之间的切换不需要陷入内核,但部分操作系统中用户态线程的切换需要内核态线程的辅助。协程是编程语言(或者

Blender关键帧动画简明教程

Blender3D是一款能够创建令人惊叹的动画的免费软件。Blender中的大多数动画都使用所谓的关键帧。Blender中关键帧的介绍将涵盖开始制作动画所需的一切!推荐:用NSDT编辑器快速搭建可编程3D场景1、什么是关键帧?在计算机出现之前,动画师必须手动绘制动画的每一帧——在每幅图像之间进行极其微小的更改。通过Bl

SpringBoot-AOP-Logback用切面拦截操作日志

在SpringBoot中使用切面来拦截操作日志,以及配合使用MyBatis-Plus框架进行操作,并使用Thymeleaf视图显示商品列表,同时配置Logback日志输出到文件。CREATETABLEproduct(idBIGINTAUTO_INCREMENTPRIMARYKEY,nameVARCHAR(255)NOT

typescript type 类型别名详解

TypeScript中的Type类型别名是一种强大的工具,用于创建自定义类型。通过类型别名,我们可以为复杂的类型结构创建更具可读性和可维护性的名字。TypeScript中的Type类型别名简介在TypeScript中,我们可以使用type关键字来定义一个类型的别名,这就是所谓的类型别名。通过类型别名,我们可以为复杂的类

Zookeeper集群 + Kafka集群

Zookeeper概述//Zookeeper定义*Zookeeper是一个开源的分布式的,为分布式框架提供协调服务的Apache项目。//Zookeeper工作机制*****Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦

javascript基础第二天笔记

JavaScript基础-第2天理解什么是流程控制,知道条件控制的种类并掌握其对应的语法规则,具备利用循环编写简易ATM取款机程序能力运算符语句综合案例运算符算术运算符数字是用来计算的,比如:乘法*、除法/、加法+、减法-等等,所以经常和算术运算符一起。算术运算符:也叫数学运算符,主要包括加、减、乘、除、取余(求模)等

易基因|ONT:三代原核甲基化在痤疮杆菌噬菌体表观遗传印迹中的工程选择性研究

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。痤疮表皮杆菌(Cutibacteriumacnes,C.acnes)是一种革兰氏阳性细菌,是人类皮肤微生物组成员。尽管是最丰富的皮肤共生体,但某些成员与常见的炎症性疾病(如痤疮)有关。各种C.acnes分支的完整基因组序列可以鉴定推定的甲基转移酶,其中一些可

如何用CRM软件系统提升销售成绩

现如今,不少企业通过办公软件优化业务效率,加强销售管理。其中CRM销售管理系统能够有效提升销售人员的工作效率,提高销售成功率。为什么CRM系统能够提升销售业绩?下面小编从三个方面来概括说一下:为什么CRM系统能够提升销售业绩?1、CRM系统帮助企业建立“以客户为中心”的商业策略。传统企业大多是“以产品为中心,只管推出产

群晖 Docker版qbittorrent 下载显示错误 解决方法

这些天在折腾AIO玩,PVE虚拟机底层,核显直通,群晖安装,免不了踩些坑。今天写篇博客,讲述一下群晖Docker版qbittorrent下载显示错误的解决方法,顺便记录一下配置,以便日后折腾可以参考。直接说结论如果下载显示错误,并且由于自己更改了存储路径,那多半是由于权限设置。去相关的文件夹中添加Owner用户的完全控

透过《眼睛的故事》:需求为何成为纪录片的“价值锚点”?

我们正处在一个内容过载、追求流量的时代。对于观众来说,这是幸运的,也是不幸的。一方面,相比以前能接受到的内容指数级增长,自己的视野无限扩大,但另一方面,“流量思维”下粗制滥制的内容不在少数,对观众来说极其不友好。在内容极为丰盛的时代,观众越来越占主导地位。早在1935年,诺贝尔经济学奖得主哈耶克就提出了“soverei

springboot 调用第三方接口的方式(一)使用RestTemplate方法

简介常用的调用第三方接口的方式:方式一:使用RestTemplate方法方式二:使用原始httpClient请求方式三:使用Feign进行消费通过HTTPClient进行访问第三方接口。但是过程比较复杂,Feign比较适合在springCLoud多模块项目中使用,所以平时基本都是使用RestTemplate方式,这样比

热文推荐