首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++ 学习笔记

a : b; } 1.5 函数模板重载 1.一个非模板函数可以和同名函数模板共存,并且函数模板可实例化为和非模板函数具有相同类型参数函数函数调用时,若匹配相同优先调用非模板函数。...若显式指定模板列表优先调用函数模板。 2.函数模板不可以进行类型自动转换,非模板函数可以。...9.2 模板和 inline 函数模板全特化后和普通函数相同函数模板一般定义在头文件中,为了避免在多个模块 include 时出现重复定义错误,一般全特化后函数模板定义为 inline。...类型转换时T被推导为int[20] } 15.4 初始化列表 1.模板实参如果是初始化列表时,无法直接完成模板参数类型 T 推导。...0) (T*) } 如上所示,main 中实例化后前两个函数完全相同,但是可以同时存在,原因是它们具有不同签名

6.6K63

《C++Primer》第十六章 模板泛型编程

函数模板 模板定义以关键字template关键字开始,后面跟着一个模板参数列表(不能为空): template int compare(const T &v1, const T...如果实参是一个左值,推断出模板实参类型将是一个左值引用,且函数参数将被实例化为一个(普通)左值引用参数T&) 这两个规则暗示我们任意类型实参传递给T&&类型函数参数对于这种类型参数,(...之前一样,名字相同函数必须具有不同数量或类型参数。 1. 编写重载模板 我们构造一组调试函数命名为debug_rep,每个函数返回一个给定对象string 表示。...多个可行模板 当多个重载模板对一个调用提供同样好匹配时,应选择最特例化版本。 3. 非模板和模板重载 对于一个调用,如果一个非函数模板一个函数模板提供同样好匹配选择非模板版本。 4....缺少声明可能导致程序行为异常 通常如果使用了一个忘记声明函数,代码编译失败。但是对于重载函数模板函数而言,如果编译器可以从模板实例化出调用匹配版本,缺少声明就不会报错。

1.7K10
您找到你想要的搜索结果了吗?
是的
没有找到

C++从入门到精通——模板

/* 该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型 通过实参a1T推演为int,通过实参d1T推演为double类型,模板参数列表中只有一个T, 编译器无法确定此处到底该...我们也可以使用auto做返回值来推,系统会自动匹配最优 示例 对于这个函数,func(1)直接调用会出错,因为系统不能推出T类型是什么,这时候我们必须使用显试实例化 auto做模板函数返回值...() { Add(1, 2); // 非模板函数匹配,编译器不需要特化 Add(1, 2); // 调用编译器特化Add版本 } 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例...如果模板可以产生一个具有更好匹配函数, 那么选择模板 // 专门处理int加法函数 int Add(int left, int right) { return left + right; } /...// Vector类名,Vector才是类型 Vector s1; Vector s2;

8510

Lambda表达式用法超详细整理!!!

Lambda我们可以将其理解为一个未命名内联函数任何函数类似,一个lambda具有一个返回类型,一个参数列表和一个函数体。 函数不同,lambda可能定义在函数内部。...必须使用尾置返回来指定返回类型 我们可以忽略参数列表和返回类型,必须永远包含捕获列表函数体 auto f=[]{return 42;};//分号不能丢 此例中,我们定义了一个可调用对象f,它不接受参数...lambda调用方式普通函数调用方式相同,都是使用调用运算符: cout<<f()<<endl;//打印42 在lambda中忽略括号和参数列表等价于指定一个空参数列表。...通常,实参和形参类型必须匹配普通函数不同,lambda不能有默认参数。 因此,一个lambda调用参数目永远参数目相等。...,函数体中还是使用了两个名字:s和cout,前者是它自己参数

72530

《C++Primer》第十三章 拷贝控制

拷贝、赋值销毁 1. 拷贝构造函数 如果一个构造函数第一个参数是自身类类型引用,且任何额外参数都有默认值,此构造函数是拷贝构造。...(100, '9'); 当使用直接初始化时,我们实际上是要求编译器使用普通函数匹配来选择与我们提供参数匹配构造函数。...参数和返回值 在函数调用过程中,具有非引用类型参数进行拷贝初始化 当一个函数具有非引用返回类型时,返回值会被用来初始化调用方结果 拷贝构造函数被用来初始化非引用类类型参数,这一特性解释了为什么拷贝构造函数自己参数必须是引用类型...&) = delete; // 阻止赋值 ~Nocopy() = default; // 合成析构函数 // 其他成员 }; 6.2 析构函数不能是删除成员 如果析构函数被删除,那么无法销毁此类型对象...这种允许移动成员函数通常使用拷贝/移动构造函数和赋值运算符相同参数模式——一个版本接受指向const左值引用,另一个版本接受一个指向非const右值引用。

1.5K40

第 13 章 拷贝控制

直接初始化时,实际上是编译器使用普通函数匹配来选择与我们提供参数匹配构造函数。而拷贝初始化是右侧运算对象拷贝到正在创建对象中,需要的话还会进行类型转换。...可以对任何函数指定 =delete,对于非拷贝控制成员,也可以引导函数匹配过程。 析构函数不能定义为 =delete。...移动构造函数,第一个参数是该类类型一个右值引用,而其他额外参数都必须有默认实参。移动构造函数不分配任何新内存,接管对象内存。...否则,这些成员默认地被定义为删除。 左值参数只能调用拷贝操作,右值参数会优先调用移动操作(精确匹配,而拷贝操作往往需要进行一次到 const转换)。...Foo someMen() & const; // 错误,const限定符必须在前 Foo otherMen() const &; // 正确 }; 如果定义两个或两个以上具有相同名字和相同参数列表成员函数

96450

第 16 章 模板泛型编程

) : data(make_shared>(b, e)) {} 模板被使用时才会进行实例化,这意味着,当两个或多个独立编译源文件使用了相同模板,并提供了相同模板参数时,每个文件中就都会有该模板一个实例...对于这种参数,对实参进行正常类型转换。 当函数返回类型参数列表中任何类型都不相同时,编译器无法推断出模板实参类型或者希望允许用户控制模板实例化,可以指定显式模板实参。...(t2), std::forward(t1) ); } ---- 16.3 重载模板 函数模板可以被另一个模板或一个普通非函数模板重载,往常一样,名字相同函数,必须具有不同数量或类型参数...往常一样,如果恰有一个函数提供比任何其他函数都更好匹配选择此函数。但是如果有多个函数提供同样好匹配: 如果同样好函数中只有一个是非模板函数选择此函数。....)); // 错误,此调用无匹配函数 return os; } 可变参数函数通常将它们参数转发给其他函数,这种函数具有容器中 emplace_back函数一样形式

1.4K20

【C++】vector模拟实现(SGI版本)

对于size_t和常引用作为参数构造来说,它匹配优先级对于10个1实际不是最高,因为常引用需要进行类模板参数T类型推导,而10又是整型intint到size_t还需要进行隐式类型转换,代价有点大...而对于迭代器区间作为参数构造来讲,函数模板参数InputIterator只需要进行一次类型推导即可完成匹配,所以用10个1来构造时,实际匹配构造函数是迭代器区间作为参数构造函数,而在匹配构造函数中...对于这种问题解决,可以size_t换成int类型,或者10强转为size_t类型,stl源码解决方式并非是这样,而是利用了函数重载来解决了这个问题,多重载了一个类型为int构造函数。...//所以可以构造函数第一个参数类型改为int库在实现时候,默认用就是size_t,我们改成int就不太好。 //那该怎么办呢?答案就是看源代码。利用重载构造解决问题。...因为对于地址这样常量不能作为变量进行传递,无法int*转换为int*& //2.所以在insert之后不要继续使用it,因为他很有可能失效,就算在vs上不失效,你能保证在其他平台下也不失效吗?

53630

第 16 章 模板泛型编程

) : data(make_shared>(b, e)) {} 模板被使用时才会进行实例化,这意味着,当两个或多个独立编译源文件使用了相同模板,并提供了相同模板参数时,每个文件中就都会有该模板一个实例...对于这种参数,对实参进行正常类型转换。 当函数返回类型参数列表中任何类型都不相同时,编译器无法推断出模板实参类型或者希望允许用户控制模板实例化,可以指定显式模板实参。...(t2), std::forward(t1) ); } ---- 16.3 重载模板 函数模板可以被另一个模板或一个普通非函数模板重载,往常一样,名字相同函数,必须具有不同数量或类型参数...往常一样,如果恰有一个函数提供比任何其他函数都更好匹配选择此函数。但是如果有多个函数提供同样好匹配: 如果同样好函数中只有一个是非模板函数选择此函数。....)); // 错误,此调用无匹配函数 return os; } 可变参数函数通常将它们参数转发给其他函数,这种函数具有容器中 emplace_back函数一样形式

1.4K60

C++11特性大杂烩

因为这个迭代器类型由一个类模板来定义,在该类模板未被实例化之前编译器是无法识别这个类型最好也增加一个用initializer_list为参数赋值运算符重载函数,来支持对列表对象进行赋值。...(老旧编译器会进行两次拷贝构造),针对内置类型消耗还算小,针对自定义类型或者容器类参数比如vector >>这种,消耗非常大,不推荐这样用。...,那么PerfectForward参数t类型是int&图片由于PerfectForward函数是万能引用,意味着通过PerfectForward函数按照传入参数类型匹配调用相同类型Func函数...必须写(parameters):参数列表普通函数参数列表一致,如果不需要参数传递,则可以连同()一起省略。...,但是报错了,原因是此时捕捉列表捕捉是父作用域变量值拷贝,具有常性无法改变且lambda函数总是一个const函数,可以在参数列表后加mutable表示取消参数常性添加mutable后运行,通过打印查看参数

87950

C++11知识点总结(全面解析C++11经常考到知识点)

int array1[] = {1,2,3,4,5}; int array2[5] = {0}; 对于一些自定义类型,却无法使用这样初始化。...vector v{1,2,3,4,5};//C++98无法编译 就无法通过编译,导致每次定义vector时,都需要先把vector定义出来,然后使用循环对其赋初始值,非常不方便。...注意: 移动构造函数参数千万不能设置成const类型右值引用,因为资源无法转移而导致移动语义失效。...C++11中,std::move()函数位于 头文件中,该函数名字具有迷惑性,它并不搬移任何东西,唯一功能就是一个左值强制转化为右值引用,然后实现移动语义。...这样做是为了保留在其他函数针对转发而来参数左右值属性进行不同处理(比如参数为左值时实施拷贝语义;参数为右值时实施移动语义) void Fun(int &x){ cout << "lvalue ref

2K10

标准库容器

在尾部之外位置插入或删除元素可能很慢 array 固定大小数组,支持快速随机访问,不能添加或删除元素 string vector相似的容器,专门用于保存字符。随机访问块。...a和b必须是相同类型(它们必须是相同容器类型,且保存相同元素类型),对于array我们还要定义它大小 C a{b,c,d,e,f,…}C a={b,c,d,e,f,…} a初始化为初始化列表中元素拷贝...返回新添加第一个元素迭代器,若列表为空,返回p_iterator 向一个vector、string或deque中插入元素会使所有指向容器迭代器、引用和指针失效 记住,insert函数元素插入到迭代器所指定位置之前...,我们元素类型对象传递给它们,这些对象被拷贝到容器中 当调用一个emplace函数时,则是参数传递给元素类型构造函数。...传递给emplace函数参数必须元素类型构造函数匹配 #include #include using namespace std; class student

66630

【泛型编程】模板全详解

,如果其他条件都相同,在调用时会优先调用非模板函数,而不会从该模板生成一个实例。...如果模板可以产生一个具有更好匹配函数,那么选择模板。...,不需要函数模板实例化 Add(1, 2.0); // 模板函数可以生成更加匹配版本,编译器根据实参生成更加匹配Add函数 } 模板函数不允许自动类型转换,普通函数可以进行自动类型转换 总结:...调用时候,若几个参数都有符合,优先匹配类型最合适。 Ⅲ. 类模板 1....这里要拿 Stack 去指定类域才对。 ② 类模板中函数在类外定义,没加 “模板参数列表” ,编译器不认识这个 T 。类模板中函数放在类外进行定义时,需要加模板参数列表

64820

【C++】初识模板,拿来吧你

<<Add(d1, d2)<<endl; /* 该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型 通过实参a1T推演为int,通过实参d1T推演为double类型,模板参数列表中只有一个...T, 编译器无法确定此处到底该T确定为int 或者 double类型而报错 注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要背黑锅 Add(a1, d1); */ //...cout(1, 2)<<endl; // 调用编译器特化Add版本 return 0; } 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例...如果模板可以产生一个具有更好匹配函数, 那么选择模板 // 专门处理int加法函数 int Add(int left, int right) { return left + right;...:类模板中函数放在类外进行定义时,需要加模板参数列表 template Vector::~Vector() { if(_pData) delete[]

25330

Linux 命令(143)—— valgrind 命令

该选项采用逗号分隔模式列表,用于 Valgrind 不应跟踪子可执行文件名称。模式可能包括元字符 ?和 *,它们具有通常含义。...如果无法指定套接字建立连接,Valgrind 会退回到输出写入标准错误(stderr)。 此选项旨在 valgrind-listener 程序结合使用。...请注意,这些启发式方法取决于 C++ 编译器生成对象布局。 它们已经使用一些 gcc 版本(例如 4.4 和 4.7)进行了测试。 它们可能无法其他 C++ 编译器一起正常工作。...这通常很重要,因为在某些环境中,使用不匹配函数释放可能会导致崩溃。 然而,有一种情况是无法避免这种不匹配。...4.5 内存申请与释放函数匹配 内存申请与释放函数匹配,如 C++ 程序中使用 malloc 申请内存,错误地使用 delete 去释放,那么 Valgrind 也可以检测出来。

3K40

C++ 特性使用建议

例如,如果v1 是一个vectorauto v2(std::move(v1))很可能不再进行大量数据复制而只是简单地进行指针操作,在某些情况下这将带来大幅度性能提升。...二者只进行了转换,没有移动对象。 3.函数重载 (1)仅在输入参数类型不同、功能相同时使用重载函数(含构造函数),当使用具有默认形参值函数(方法)重载形式时,需要注意防止二义性。...某些情况下,一个单元测试类声明成待测类友元会很方便。 友元扩大了(没有打破)类封装边界。...某些情况下,相对于类成员声明为 public,使用友元是更好选择,尤其是如果你只允许另一个类访问该类私有成员时。当然,大多数类都只应该通过其提供公有成员进行互操作。...优点: 有了流,在打印时不需要关心对象类型,不用担心格式化字符串参数列表匹配,并且流构造和析构函数会自动打开和关闭对应文件。 缺点: 流使得 pread() 等功能函数很难执行。

1.6K20

初识C++模板

对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配函数, 那么选择模板。...模板函数不允许自动类型转换,普通函数可以进行自动类型转换 3、类模板 3.1 类模板定义格式 template class...需要加模板参数列表 template Vector::~Vector() { if(_pData) delete[] _pData; _size = _...例如:vector::~vector( ) 3.2 类模板实例化 类模板实例化函数模板实例化不同,类模板实例化需要在类模板名字后跟,然后实例化类型放在中即可,类模板名字不是真正类...// Vector类名,Vector才是类型 Vector s1; Vector s2; 3.3 类模板分文件编写 在类模板分文件编写后运行程序,我们就发现出问题了

38650

Google C++ 编程风格指南(五):其他 C++ 特性

输入参数可以是 const 指针, 不能是非 const 引用参数,除非用于交换,比如 swap(). 有时候,在输入形参中用 const T* 指针比 const T& 更明智。...例如, 如果 v1 是一个 vector, auto v2(std::move(v1)) 很可能不再进行大量数据复制而只是简单地进行指针操作, 在某些情况下这将带来大幅度性能提升...某些情况下, 一个单元测试类声明成待测类友元会很方便. 友元扩大了 (没有打破) 类封装边界....某些情况下, 相对于类成员声明为 public, 使用友元是更好选择, 尤其是如果你只允许另一个类访问该类私有成员时. 当然, 大多数类都只应该通过其提供公有成员进行互操作. 5.7....宏可以做一些其他技术无法实现事情, 在一些代码库 (尤其是底层库中) 可以看到宏某些特性 (如用 # 字符串化, 用 ## 连接等等). 但在使用前, 仔细考虑一下能不能不使用宏达到同样目的.

1.1K30

《C++Primer》第七章 类

对于某些类,合成默认构造函数可能执行错误操作:如果定义在块中内置类型或符合类型(比如数组和指针)对象被默认初始化,它们值可能是未定义。...编译器可能不能某些类合成默认构造函数:如果类中包含一个其他类类型成员并且这个成员类型没有默认构造函数,那么编译器无法初始化该成员。...因为非常量版本函数对于常量对象是不可用,所以我们只能在一个常量对象上调用const成员函数。虽然可以在非常量对象上调用常量版本或者非常量版本,显然非常量版本是一个更好匹配。...构造函数初始值列表 // 一般构造函数写法: 是用初始值列表 Sales_data(const std::string &s, unsigned n, double p) : bookNo(s),...最好令构造函数初始值顺序成员声明顺序一致,而且可能的话尽量避免使用某些成员初始化其他成员。 3.

53620

第 18 章 用于大型程序工具

搜寻匹配 catch语句过程中,寻找是第一个异常匹配 catch语句,是按照其出现顺序逐一进行匹配,当程序使用具有继承关系多个异常时,要注意令派生类异常处理代码出现在基类异常处理代码之前...其形式如下: template Blob::Blob() try : data(std::make_shared>(i1)) {...如果using声明所在作用域中已经有一个函数新引入函数同名且形参列表相同该using声明将引发错误。..., using声明不同是,对于 using指示来说,引入一个已有函数形参列表完全相同函数并不会产生错误。...在 C++11新标准中,允许派生类从它一个或几个基类中继承构造函数,但是如果从多个基类中继承了相同构造函数(即形参列表完全相同),程序产生错误。

89420
领券