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

现代C++之SFINAE

根据名称找出所有适用函数和函数模板对于适用函数模板,要根据实际情况对模板形参进行替换; 替换过程中如果发生错误,这个模板会被丢弃 在上面两步生成可行函数集合中,编译器会寻找一个最佳匹配,产生对该函数调用...一个简单函数调用,如“f(obj);”在c++中,激活一个机制,根据参数obj来确定应该调用哪个f函数。...在某些情况下,如果替换导致无效代码,编译器不应该抛出大量错误,而应该继续尝试其他可用重载。SFINAE概念只是为“健全”编译器保证这种“健全”行为。...它只是尝试下一个重载。 再来回顾一下上述简单理解:替换就是尝试用提供类型或值替换模板参数机制。在某些情况下,如果替换导致无效代码,编译器不应该抛出大量错误,而应该继续尝试其他可用重载。...您编译器确实是个好人,不会遗忘任何分支,因此在这种情况下,obj必须同时具有serialize方法和to_string重载

2.9K20

C++那些事之SFINAE

根据名称找出所有适用函数和函数模板对于适用函数模板,要根据实际情况对模板形参进行替换; 替换过程中如果发生错误,这个模板会被丢弃 在上面两步生成可行函数集合中,编译器会寻找一个最佳匹配,产生对该函数调用...一个简单函数调用,如“f(obj);”在c++中,激活一个机制,根据参数obj来确定应该调用哪个f函数。...在某些情况下,如果替换导致无效代码,编译器不应该抛出大量错误,而应该继续尝试其他可用重载。SFINAE概念只是为“健全”编译器保证这种“健全”行为。...它只是尝试下一个重载。 再来回顾一下上述简单理解:替换就是尝试用提供类型或值替换模板参数机制。在某些情况下,如果替换导致无效代码,编译器不应该抛出大量错误,而应该继续尝试其他可用重载。...您编译器确实是个好人,不会遗忘任何分支,因此在这种情况下,obj必须同时具有serialize方法和to_string重载

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

浅谈 C++ 元编程

1994 年 C++ 标准委员会会议上,Erwin Unruh 演示了一段利用编译器错误信息计算素数代码。...然后根据 SFINAE 规则: 使用 std::enable_if 重载函数 ToString,分别对应了数值、C 风格字符串和非法类型; 在前两个重载中: 分别调用 std::to_string 和...假设调用 ToString ("str"),在编译这段代码时,std::string (const char *) 可以正确重载,但是 std::to_string (const char *) 并不能找到正确重载...函数 _Factor 有两个重载:一个是对任意非负整数,一个是对 0 为参数。前者利用递归产生结果,后者直接返回结果。...当调用 _Factor 时,编译器会展开为 2 * _Factor,然后 _Factor 再展开为 1 * _Factor,最后 _Factor 直接匹配到参数为 0 重载

3K61

C++】——入门基础知识超详解

通过使用缺省参数,可以使函数调用更加简洁,避免在多次调用中重复传递相同实参。 5. 函数重载 在自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实含义,即该词被重载了。...这展示了同一个表达可以有不同解释。 同样地,在C++中,函数也可以重载。 5.1 函数重载概念 函数重载:是指在同一作用域中声明几个功能类似但参数不同同名函数。...; // 调用 Print(const std::string&) return 0; } 5.2 C++支持函数重载原理 -- 名字修饰 (Name Mangling) 为什么C+...内联函数 7.1 概念 内联函数是使用 inline 关键字修饰函数。在编译时,C++编译器会在调用内联函数地方直接展开函数体,而不是进行正常函数调用。...含义不明确导致容易出错:复杂类型名可能会导致理解上混淆。

7910

第4章 | 移动

会将纯字符串字面量(如 "udon")放在只读内存中,因此为了与 C++ 示例和 Python 示例进行更清晰比较,此处调用to_string 以获取堆上分配 String 值。...Rust 明智地禁止使用未初始化值,因此编译器会拒绝此代码并报告如下错误: error: use of moved value: `s` | 7 | let s = vec!...如果想达到与 C++ 程序相同状态(每个变量都保存一个独立结构副本),就必须调用向量 clone 方法,该方法会执行向量及其元素深拷贝: let s = vec!...同样,to_string 调用返回是一个新 String 实例。 构造出新值 新 Person 结构体 name 字段是用 to_string 返回值初始化。...虽然 C++ 允许重载赋值运算符以及定义专门复制构造函数和移动构造函数,但 Rust 并不允许这种自定义行为。在 Rust 中,每次移动都是字节级一对一浅拷贝,并让源变成未初始化状态。

6310

C++11较C++03改进

1、关键词auto修订 一门语言如果太啰嗦了,不仅会为阅读带来障碍,而且还是许多错误根源。所以从C语言继承而来关键词auto在C++11中有了新定义,可以进行自动类型推断。...例如: 需要谨慎一些应用 2、for()循环范围 迭代操作在STL中是很常见。C++11提供了一个专门for函数来简化那些以begin()、end()为参数并返回迭代器函数。...例如: 列表初始化也可以运用在更复杂结构中,如下所示: 4、C++数组 貌似这块儿是C++11添加功能。 C++11提供了std::array,目的是来取代C中数组。...通过以下重载函数: string to_string(int) string to_string(float) string to_string(double) 6、支持C++11编译器...1.GNU C++ 编译器需要加入 -std=c++0x 来编译 C++11 代码。

1.3K30

c++ 字符串流 sstream(常用于格式转换)

点我进入原文 c++ 字符串流 sstream(常用于格式转换) 使用stringstream对象简化类型转换 C++标准库中提供了比ANSI C更高级一些功能...错误格式化符 在这种情况下,程序员错误地使用了%f格式化符来替代了%d。因此,s在调用完sprintf()后包含了一个不确定字符串。要是能自动推导出正确类型,那不是更好吗?...库是最近才被列入C++标准。(不要把与标准发布前被删掉弄混了。)因此,老一点编译器,如GCC2.95,并不支持它。...如果你恰好正在使用这样编译器而又想使用的话,就要先对它进行升级更新。...你可以通过重载来支持自定义类型间转换。 一些实例: stringstream通常是用来做数据转换。 相比c库转换,它更加安全,自动和直接。

94220

C++之函数重载

函数重载执行同样一般性动作,但是应用在不同形参类型上,调用这些函数时,无需担心调用是哪个函数,就像我们不必操心执行整数算术操作还是浮点数算术操作就可以实现 int 型加法或 double 型加法一样...事实上C++是支持模板函数。我们也可以使用模板函数来实现参数个数相同重载函数功能。 当然了,main函数是不能被重载。它是留给操作系统接口。...函数重载是根据函数参数来匹配函数,因此匹配可能出现下面的几种结果: 1.完全匹配,调用成功。编译器会自动寻找最佳匹配来调用。 2.参数不匹配,调用失败。...3.存在多个与实参匹配函数,调用具有二义性。这种情况发生一般是由于参数隐式类型转换或者是重载函数函数参数具备默认值。...:f(3);这时候编译器会告诉你对重载函数调用不明确

72920

string和stringstream用法「建议收藏」

举个例子: 題目:输入第一行有一个数字 N 代表接下來有 N 行资料,每一行资料里有不固定个数整数(最多20个,每行最大200个字元),编程將每行总和打印出來。...但是,对上面代码一个微小改变就会使程序发生错误 printf("%s\n", s); sprintf(s, "%f", n); //错误格式化符 printf("%s\n", s); return...因此,s在调用完sprintf()后包含了一个不确定字符串。要是能自动推导出正确类型,那不是更好吗?...进入stringstream: 由于n和s类型在编译期就确定了,所以编译器拥有足够信息来判断需要哪些转换。库中声明标准类就利用了这一点,自动选择所必需转换。...你可以通过重载来支持自定义类型间转换。 5.一些实例 stringstream通常是用来做数据转换。相比c库转换,它更加安全,自动和直接。

81340

C++】深入剖析C++11新特性

+ 对函数重写要求比较严格,但是有些情况下由于疏忽,可能会导致函数名字母次序写反而无法构成重载,而这种错误在编译期间是不会报出,只有在程序运行时没有得到预期结果才来debug 会得不偿失,因此: C...拷贝赋值重载 5. 取地址重载 6. const 取地址重载 最后重要是前4个,后两个用处不大。默认成员函数就是我们不写编译器会生成一个默认。...针对移动构造函数和移动赋值运算符重载有一些需要注意点如下: 如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载任意一个。那么编译器会自动生成一个默认移动构造。...如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载任意一个,那么编译器会自动生成一个默认移动赋值。...实际在底层编译器对于lambda表达式处理方式,完全就是按照函数对象方式处理,即:如果定义了一个lambda表达式,编译器会自动生成一个类,在该类中重载了operator(),类名会用一串随机字符串来代表

34040

C++入门

C++是通过函数修饰规则来区分,只要参数不同,修饰出来名字就不一样,就支持了重载。如果两个函数函数名和参数是一样,返回值不同是不构成重载,因为调用编译器没办法区分。...内联函数以inline修饰函数叫做内联函数,编译时C++编译器会在调用内联函数地方展开,没有函数调用建立栈帧开销,内联函数提升程序运行效率 。...(即函数不是很长,具体没有准确说法,取决于编译器内部实现)、不是递归、且频繁调用函数采用inline修饰,否则编译器会忽略inline特性 inline不建议声明和定义分离,分离会导致链接错误。...出来函数地址导致链接错误swap.cppswap.htest.cppauto关键字随着程序越来越复杂,程序中用到类型也越来越复杂:类型难于拼写含义不明确导致容易出错 加入auto关键字类似于python...如果使用 auto 关键字,编译器就无法确定参数类型,只有在调用函数时候,才能根据实参来推导出形参类型,否则就会导致编译错误

17120

C++ 11 nullptr关键字

熟悉C++童鞋都知道,为了避免“野指针”(即指针在首次使用之前没有进行初始化)出现,我们声明一个指针后最好马上对其进行初始化操作。如果暂时不明确该指针指向哪个变量,则需要赋予NULL值。...C/C++NULL到底是什么我们查看一下C和C++源码,不难发现:1.NULL在C++定义,NULL在C++中被明确定义为整数0:/* Define NULL pointer value */...简单地说,C++之所以做出这样选择,根本原因和C++函数重载机制有关。...考虑下面这段代码:void Func(char *);void Func(int);int main(){ Func(NULL);}如果C++让NULL也支持void *隐式类型转换,这样编译器就不知道应该调用哪一个函数...NULL值是0,所以调用了Func(int)。

2.4K20

c++字符串与c字符串

在Microsoft Visual Studio中使用C风格字符串函数时,编译器可能会给 出安全相关警告甚或错误,说明这些函数已经被废弃了。...事实上,把string想象为 简单类型更容易发挥string作用。通过运算符重载神奇作用,C++string使用起来比C字符串容易得多。 ...>>输出到字符串, 必须每次都调用clear()方法  3.2.3 c++常用字符串函数  函数功能append将字符添加到字符串末尾at返回字符串中指定位置处元素引用c_str将字符串内容转换为...如果像下面这样编写普通字符串字面量,那么会收到一个编译器错误,因为 字符串包含了未转义引号:  string str = "Hello "World"!// Error!...例如,如果像下面这样编写普通字符串字面量,那么会收到一个编译器错误,因为普通字符串字面量不能跨越多行:  string str = "Line 1 Line 2 with \t"; // Error

1.4K30

C++】C++11 右值引用和移动语义

此时我们再调用 to_string 函数与之前结果进行比对: 和上面一样,本来这里 str 会先拷贝构造一个临时对象,由于临时对象属于右值,所以会直接调用移动拷贝来构造 s;但是这里编译器进行了优化...---- 六、新增默认成员函数 在 C++11 之前,C++ 类一共有六个默认成员函数: 构造函数 析构函数 拷贝构造函数 拷贝赋值重载 取地址重载 const 取地址重载 由于 C++11 设计出了右值引用...默认生成移动赋值函数,对于内置类型成员会完成浅拷贝,对于自定义类型,如果其实现了移动赋值,就调用移动赋值,如果没有实现就调用赋值重载。...,没有实现就调用自定义类型拷贝构造和赋值重载。..._ptr) {} int* _ptr; }; 但是上面这种做法只防止了在类外进行拷贝,而在类内我们仍然可以调用拷贝构造函数完成拷贝,此时编译器在编译时不会发生错误,只有运行起来对同一块空间析构两次时才会报错

65410

C++11『右值引用 ‖ 完美转发 ‖ 新增类功能 ‖ 可变参数模板』

,将临时资源等将亡值资源通过 移动构造 进行转移,减少拷贝 2.完美转发 泛型编程 是 C++核心功能之一,典型让程序员少走弯路,让编译器多干活,伴随着 右值引用 新概念加入,泛型编程 也需要随之升级...析构、拷贝构造、赋值重载任意一个,那么编译器才会自动生成一个 移动构造 函数,移动构造 函数对于内置类型,会按字节拷贝,对于自定义类型,会去调用 移动构造 函数,如果没有,就调用 拷贝构造(...如果我们实现了 析构、拷贝构造、赋值重载,就证明当前类中涉及到了 动态内存管理,是需要自己进行 深拷贝 编译器无能为力,移动语义 也应该根据自己实际场景进行设计,所以编译器就没有自动生成 如何自己实现这两个...可变参数模板 传参简单,可变参数包 解析就麻烦了,下面是一种不被编译器支持错误解析方式 template void showList(Args... args) {...// 错误解析参数方式 int n = sizeof...

34650

string和stringstream用法详解「建议收藏」

错误格式化符 在这种情况下,程序员错误地使用了%f格式化符来替代了%d。因此,s在调用完sprintf()后包含了一个不确定字符串。要是能自动推导出正确类型,那不是更好吗?...库是最近才被列入C++标准。(不要把与标准发布前被删掉弄混了。)因此,老一点编译器,如GCC2.95,并不支持它。...如果你恰好正在使用这样编译器而又想使用的话,就要先对它进行升级更新。...你可以通过重载来支持自定义类型间转换。 一些实例: stringstream通常是用来做数据转换。 相比c库转换,它更加安全,自动和直接。...,必须调用stringstream成员函数clear().

1.1K20

C++】C++11中常见语法(上)

Young::to_string 函数中会先用返回 ret 生成构造生成一个临时对象,但是我们可以看到,编译器把 ret 识别成了右值,即将亡值,调用了移动构造。...然后在把这个临时对象做为 Young::to_string 函数调用返回值赋值给接收 ret,这里调用移动赋值。...默认成员函数 原来 C++ 类中,有 6 个默认成员函数: 构造函数 析构函数 拷贝构造函数 拷贝赋值重载 取地址重载 const 取地址重载 最后重要是前4个,后两个用处不大。...默认成员函数就是我们不写编译器会生成一个默认。 C++11 新增了两个:移动构造函数和移动赋值运算符重载。...如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载任意一个,也就是都没有实现,那么编译器会自动生成一个默认移动赋值。

14810

从零开始学C++之从C到C++(一):const与#define、结构体对齐、函数重载name mangling、newdelete 等

静态) 函数重载不同形式: 形参数量不同 形参类型不同 形参顺序不同 形参数量和形参类型都不同 调用重载函数时,编译器通过检查实际参数个数、类型和顺序来确定相应调用函数...(int i); void abs(int i); //如果返回类型不同而函数名相同、形参也相同,则是不合法编译器会报"语法错误"。...C编译器编译,则__cplusplus 没有定义,extern “C" 被略过,如果头文件被C++代码包含并被C++编 译器编译,存在__cplusplus 定义故extern "c" 提示编译器不要对...不同C++编译器name mangling 方案是不同,这是造成不同编译器之间存在二进制连接兼容性主要原因之一。...,也可以是第二个,因此编译器不能确定调用是哪一个函数。

1.2K00

C++ 初识函数模板

,无法知道 f和f1函数谁先会被调用(也就无法确定第一次编译时间点),但为了保证编译期间完成实例化工作,早期C++编译器采用对同一实例每一次出现地方都编译策略,然后从多个编译结果中选一个作为最终结果...C++充许显式实例化声明,用来显示指定某一个函数模板实例化时间点,从而解决同一个实例被多次编译问题。...2.3 实参推导所谓实参推导,在使用函数模板时省略,不明确指定数据类型参数,而是由编译器根据函数实参类型自动推导出类型参数真正类型。...了解什么是实参推导后,使用时,需要知道实参推导是不支持自动类型转换。如下代码是错误。...重载函数模板C++中普通函数和函数模板可以一起重载,面对多个重载函数,编译器需要提供相应匹配策略。

59540
领券