视频笔记 CppCon 2015:Marshall Clow “Type Traits - what are they and why should I use them?"

Video: CppCon 2015:Marshall Clow “Type Traits - what are they and why should I use them?"

https://www.youtube.com/watch?v=VvbTP_k_Df4

如果你需要写关于不同类型的代码,而不是具体的类型,你可能需要了解Type Traits

4:47 C++多少种类型?14

  • void, nullptr: 只有一个成员在这个type里面
  • struct 实际上和class 是一样的,只是default access是public
  • array vs pointer: array有一片物理区域,pointer仅仅是个地址。pointer可以为空

8:00 类型分类

08:21 type trait的定义

就是一个结构,里面包含模板的类型信息

例如,下面是个简单用法,输出true/false

#include <iostream>

#include <type_traits>

std::cout << std::is_floating_point<float>::value << ‘\n‘; // true

std::cout << std::is_floating_point<int>::value << ‘\n‘; // false

std::rank的用法,输出int

std::cout << std::rank<float>::value << ‘\n‘; // 0

std::cout << std::rank<int[1][1]>::value << ‘\n‘; // 2

std::cout << std::rank<int[2][3][4]>::value << ‘\n‘; // 3

有些可以输出type

std::remove_const<const int>::type --> int

std::remove_const<int>::type--> int

BTW:

  1. std::is_permulation 比较两个序列是否相同,顺序可以不同
  2. std::enable_if & SAFINAE

enable_if 的主要作用就是当某个 condition 成立时,enable_if可以提供某种类型。enable_if在标准库中通过结构体模板实现的

SFINAE 的的全称是 Substitution Failure Is Not An Error

SFINAE 是C++ 的一种语言属性,具体内容就是”从一组重载函数中删除模板实例化无效的函数”

19:20 这个视频认为SFINAE是C++里第二丑陋的缩略语。第一是RAII,因为根本就无法读出来。

下面的例子不是来自本视频

// long multiply(int i, int j) { return i * j; }

template <class T>

typename T::multiplication_result multiply(T t1, T t2)

{

return t1 * t2;

}

void test()

{

multiply(4, 5); // error

}

error C2893: Failed to specialize function template ‘T::multiplication_result multiply(T,T)‘

如果把第一行的注释去掉,这个error就会消失。这就是因为SFINAE原则,编译器会尝试所有的匹配,找到最合适的,其它不合适的有错也忽略。

19:48 SFINAE Example

int func(...) { return 0; }

template <typename T>

typename std::enable_if<std::is_integral<T>::value, int>::type

func(T val) {

return 1;

}

int func(float f) { return 2; }

void test()

{

std::cout << func(nullptr) << " ";

std::cout << func(2) << " ";

std::cout << func(2.f) << " ";

std::cout << func(2.0) << "\n";

}

输出: 0 1 2 2

第1行是C语言的不定参数的函数,经典例子是printf,和C++11的variadic arguments 不同。这一行匹配的优先级最低。

第4行,如果T不是整数类型时,会产生编译错误。根据SFINAE原则,使用其它的函数来匹配。

31:40

可以针对一些类型提供优化

32:00 优化的例子

每个人都觉得自己实现的vector会比stl的好。但事实上,STL里面的实现包含许多corner cases,非常复杂。

strong exception guarantee: 要么完全成功,要么出错抛异常,并且需要完全恢复的操作前的状态。例如,如果vector内存reserve不够,需要申请新的内存,并且把已经有的对象拷贝进入新内存。如果拷贝到一半出错,需要完全恢复这些操作,让vector恢复到之前的状态,并且抛出异常。

拷贝的代价很高(需要创建,构造,析构旧对象)。如果T支持move,可以利用move提高效率。但是如果move构造函数会抛出异常,既无法继续,又无法恢复!所以,必须要求no throw move-constructible! no throw意味着move永远都能成功。并不是所有的T都能实现no throw的,需要特别留意。

如果vector里面是int,或者T是个结构只包含基本类型。只要申请新内存,拷贝内存(never throw),释放旧内存,效率可言很高。有一种type trait叫做trivially copyable描述这种情况。

这些都不是必要的,没有这些也能正确实现。但是有了这些,可以优化得很好。

43:06 Questions

  • 44:00 可以生成自己的type trait吗?可以。例如,std::is_floating_point,如果自己实现该怎么实现。针对float, double, long double这几种类型特化,返回true,默认返回false。有方法甚至可以实现这样的type trait: 一个结构是否包含一个member function叫做foo,并且参数是什么什么,返回什么。
  • 47:05 对 SFINAE 的例子,一般有两种实现,一种是使用enable_if,另一种...。enable_if 有什么优势?这种方法更简单清晰,不容易出错。具体见视频。
  • 50:16 是的,将来 concept 的引入会很大程度的改变现在的实现
时间: 2024-10-30 05:49:40

视频笔记 CppCon 2015:Marshall Clow “Type Traits - what are they and why should I use them?"的相关文章

视频笔记 CppCon 2016 Chandler Carruth High Performance Code 201 Hybrid Data Structures

版权声明:转载请说明出处 http://www.cnblogs.com/eagledai/ https://www.youtube.com/watch?v=vElZc6zSIXM&t=1157s LLVM internal data structures LLVM 内部数据结构 2:24 SmallVector 下面是 SmallVector 的简化版本.这是 LLVM 里最基本的数据结构,到处被使用. 问题:为什么不直接使用 STL 的 vector? 因为在 STL 里,如果对 vector

Android老罗视频笔记-http-1

---恢复内容开始--- 以下是看老罗视频的笔记: (所有图片来自老罗视频的截图) 一.老罗视频教程思路:android入门介绍-->百度地图介绍-->常用UI布局的介绍-->常用的UI的控件.(应用开发控件:HTTP协议编程了解服务器与安卓之间的交互.) 二.WWW是以Internet作为传输媒介的一个应用程序,WWW网上基本的传输单位是Web网页.B-S结构.WWW的工作是基于客户机/服务器计算模型(j2ee).由Web浏览器和Web服务器构成,两者之间采用超文本传输协议HTTP进行

Java学习笔记(2015.7.27~7.31)

Java学习笔记(2015.7.27~7.31) Java 课堂 Java学习笔记(2015.7.27~7.31) 小技巧 常用方法 1.List另一个子类--LinkedList 2.数组的常用方法 3.排序 1.二分法查找 2.数组转换为List 3.可变参数Type ... param (了解) 1.容器Collection 2.自动拆装箱(了解) 3.JDK增强for循环(了解) 4.泛型(掌握) 5.iterator与for在迭代中的区别 1.概念:保存多个对象的对象. 2.JDk为什

虚幻4视频笔记002:精简StarterContent文件夹体积

#虚幻4#视频笔记:精简StarterContent文件夹体积 . 在很多练习项目和测试项目中,都会使用StarterContent文件夹,但是该文件夹体积巨大,如果项目数量多会占用大量空间,并且分享起来也很麻烦.这里提供了一种精简体积的简单方法.注意明确视频内容后再对项目进行精简,并且也不要在生产环境中使用这个技巧. 油管: http://t.cn/Rtgk4is 度盘:http://t.cn/Rtgk46v

type traits

Type Traits,  类型萃取,这个概念涉及到的内容太多.基本常用的萃取方法可以参考 http://en.cppreference.com/w/cpp/types 这里主要记录一下对函数的萃取技巧. 1 template<typename R, typename ...Args> 2 R FuncWrapper(R(*func)(Args...), Args&&... args) 3 { 4 return func(std::forward<Args>(arg

格式工厂(七)Type Traits

版权声明:本文为博主原创文章,未经博主允许不得转载. 识别变量的type id,返回true或false,举一个简单使用的例子 template <typename T> void type_traits_output(const T& x) { cout << "\ntype traits for type : " << typeid(T).name() << endl; cout << "is_void\

Java 学习笔记(2015.7.13~17)

Java 学习笔记(2015.7.13~17) Java this关键字 表示本类中的属性,调用本类中的方法 class Person {        private String name;         private int age;         public Person(String name, int age) {         this.name = name;//调用本类中的属性         this.age = age;//同上} //get&set方法:    

Java 学习笔记(2015.7.20~24)

Java 学习笔记(2015.7.20~24) Java Java 学习笔记(2015.7.20~24) 1.StringBuffer与StringBuilder的区别: 2.基本数据类型包装类 3.Date.Calendar.DateFormat等与时间相关的类 1.常用类String 2.正则表达式 3.常用类 StringBuffer 代表可变的字符序列 拆箱与装箱 包装类的应用 匿名内部类 数组 day11 day12 day13 day14 day11 父类中使用public定义的方法

c++11 : static_assert和 type traits

static_assert提供一个编译时的断言检查.如果断言为真,什么也不会发生.如果断言为假,编译器会打印一个特殊的错误信息. 1 2 3 4 5 6 7 8 9 10 11 12 13 template <typename T, size_t Size> class Vector {    static_assert(Size < 3, "Size is too small");    T _points[Size]; }; int main() {    Vec