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

C++ 特性使用建议

2.右值引用 建议:只在定义移动构造函数与移动赋值操作时使用右值引用,区分std::move与std::forward作用。...3.函数重载 (1)仅在输入参数类型不同、功能相同时使用重载函数(含构造函数),当使用具有默认形参值函数(方法)重载形式时,需要注意防止二义性。...void TestFunction2(vector v) {} TestFunction2({1,2,3}); 用户自定义类型也可以定义接收 std::initializer_list 构造函数和赋值运算符...,哪怕没有接收 std::initializer_list 构造函数。...如果你使用递归模板实例化,或者类型列表,或者元函数,又或者表达式模板,或者依赖SFINAE,或者sizeof trick 手段来检查函数是否重载,那么这说明你模板用太多了,这些模板太复杂了,我们不推荐使用

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

【重学 C++】06 | C++该不该使用 explicit

单入参std::initializer_list构造函数std::initializer_list 是 C++11 中引入一种特殊类型,用于简化在初始化对象时传递初始化列表过程。...下面是一个简单使用例子:class MyClass {public:MyClass(std::initializer_list numbers) {// 构造函数实现}};int main...() {MyClass obj = {1, 2, 3, 4, 5}; // 使用初始化列表语法进行隐式转换}对于带有std::initializer_list类型参数构造函数,也不推荐使用explicit...因为使用std::initializer_list作为构造函数入参,就是为了方便初始化对象。...对于带有单入参std::initializer_list构造函数,也不推荐使用explicit,以方便使用初始化列表语法进行隐式转换。同类型扩展类,为了避免差异化,隐式转换会更合适

20700

第七章 函数

x + y; } 函数详解 参数 函数可以在函数小括号中包含零到多个形参 包含零个形参时,可以使用void标记 对于非模板函数来说,其每个形参都有确定类型,但形参可以没有名称 形参名称变化并不会引入函数不同版本...函数可以定义缺省实参 如果某个形参具有缺省实参,那么它右侧形参都必须具有缺省实参 在一个翻译单元中,每个形参缺省实参只能定义一次 具有缺省实参函数调用时,传入实参会按照从左到右顺序匹配形参...+11引入方式:位于函数后部(泛型编程和类成员函数编写可能会简化编写) C++14引入方式:返回类型自动推导 使用constexpr if构造“具有不同返回类型...:使用相同函数名定义多个函数,每个函数具有不同参数列表(参数个数或者参数类型不同) 不能基于不同返回类型进行重载 函数重载与name mangling 编译器如何选择正确版本完成函数调用...小心:Most vexing parse,尝试使用大括号替换小括号,明确表示我们要构造一个对象而不是声明一个函数

16930

C++那些事之SFINAE

overload resolution, SFINAE and the static behavior of sizeof 2.1重载决议 当一个函数名称和某个函数模板名称匹配时,重载决议过程大致如下:...解决方案包括将序列化功能分为两个不同功能:一个仅使用obj.serialize(),另一个根据obj类型使用to_string。 我们回到一个已经解决较早问题,如何根据类型拆分?...SFINAE,可以肯定!到那时,我们可以将hasSerialize函数重新构造为序列化函数,并使其返回std :: string而不是编译时boolean。但是我们不会那样做!...如您所见,auto允许使用尾随返回类型语法,并使用decltype以及涉及函数参数之一表达式。这是否意味着我们可以使用它来测试SFINAE序列化存在? 是的,沃森博士!...5.2 重建is_valid 现在,我们已经有了一种非常时尚方式,可以使用lambda生成具有潜在SFINAE属性未命名类型,我们需要弄清楚如何使用它们!

2.2K20

c++17好用新特性总结

auto x5{ 3 }; // std::initializer_list 这三种方式初始化变量,最终类型推导结果都是 std::initializer_list ,...std::tuple隐式推导 在c++17以前,构造std::pair/std::tuple时必须指定数据类型使用std::make_pair/std::make_tuple函数,c++17为std...只有当对类型完全未知情况下,才应当使用std::any,比如动态类型文本解析或者业务逻辑中间层信息传递。...常用于可能失败函数返回值中,比如工厂函数。在C++17之前,往往使用T*作为返回值,如果为nullptr则代表函数失败,否则T*指向了真正返回值。...总结一下,c++17新增三种类型给c++带来了更现代更安全类型系统,它们对应使用场景是: std::any适用于之前使用void*作为通用类型场景。

3K10

《Effective Modren C++》 进阶学习(上)

另外,在构造函数有参数情况中,若不包含std::initializer_list参数或者 构造未传入实参,()和{}产生一样效果,否则{}优先匹配std::initializer_list参数构造函数...T类型,就会只匹配std::initializer_list构造函数。...在构造重载匹配中,只要参数能够强转std::initializer_listT,就会匹配std::initializer_list构造函数,即便有更加匹配构造函数。...当使用{}初始化无参数时,会优先匹配默认构造函数,如果要匹配std::initializer_list构造函数,需要传入{}。 8....需要使用默认实现,则用default声明;不希望某个成员函数被调用,则使用delete声明;需要自定义实现,则自定义实现接口。

17120

现代C++之SFINAE

overload resolution, SFINAE and the static behavior of sizeof 2.1重载决议 当一个函数名称和某个函数模板名称匹配时,重载决议过程大致如下:...解决方案包括将序列化功能分为两个不同功能:一个仅使用obj.serialize(),另一个根据obj类型使用to_string。 我们回到一个已经解决较早问题,如何根据类型拆分?...SFINAE,可以肯定!到那时,我们可以将hasSerialize函数重新构造为序列化函数,并使其返回std :: string而不是编译时boolean。但是我们不会那样做!...如您所见,auto允许使用尾随返回类型语法,并使用decltype以及涉及函数参数之一表达式。这是否意味着我们可以使用它来测试SFINAE序列化存在? 是的,沃森博士!...5.2 重建is_valid 现在,我们已经有了一种非常时尚方式,可以使用lambda生成具有潜在SFINAE属性未命名类型,我们需要弄清楚如何使用它们!

2.9K20

【C++11特性篇】C++11中新增initializer_list——初始化小利器(2)

return 0; } 二.std::initializer_list使用场景(初始化容器对象,作为operator=参数…) std::initializer_list一般是作为构造函数参数...C++11对STL中不少容器 (vector,list,map…) 就 增加std::initializer_list作为参数构造函数 ,这样初始化容器对象就更方便了 std::initializer_list...也可以作为operator=参数 ,这样就可以用大括号赋值 三.对比【C++11特性{ }隐式类型转换】&【调用initializer_listvector构造函数】不同原理 C++11中新增关于...{}用法 (传送门):具体对象是下面代码中Point, 直接调用两个参数构造 – 隐式类型转换 我们vector容器构造函数参数是std::initializer_list, 这里是调用initializer_list...-- 隐式类型转换 return 0; } 四.std::initializer_list文档传送门 initializer_list 文档传送门

29810

【笔记】《深入理解C++11》(上)

, 所以当发生冲突时候应该显式声明构造函数来因此冲突函数 当派生类是虚继承了基类时, 不能使用继承构造函数 一旦使用了继承构造函数(用using Base::Base;)暴露出来, 自身默认构造函数就和之前隐藏规则一样...如果使用委派构造, 就必须在构造函数体中进行其余成员初始化 一种解决方案是修改构造顺序, 让参数最多构造函数作为委派构造最终目标, 然后在这个构造函数初始化列表中完成成员初始化....大括号初始化会制止类型收窄 大括号返回值是initializer_list, 可以用作函数一种重载参数 大括号也可以在return, 一般用来构造临时变量, 具体构造出来临时变量还是依靠声明返回值决定...下面是这类做法一个简单样例 // From: https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error // 这段在展示如何利用模板在编译器判断模板参数是否具有某个定义符号...各种匿名类型也都可以被重新命名并重用了 decltype只能以表达式作为参数, 所以需要获取某个函数返回类型时可以用虚假参数进行传入, 注意decltype是编译期进行, 因此不会真正运行这个函数

1.8K20

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

类似引用崩溃, 移动构造函数自动推导这样规则都是很复杂. 结论: 只在定义移动构造函数与移动赋值操作时使用右值引用, 不要使用 std::forward 功能函数....> 构造函数和赋值运算符,以自动列表初始化: class MyType { public: // std::initializer_list 专门接收 init 列表。...MyType m{2, 3, 5, 7}; 最后,列表初始化也适用于常规数据类型构造,哪怕没有接收 std::initializer_list 构造函数。...double d{1.23}; // MyOtherType 没有 std::initializer_list 构造函数, // 直接上接收常规类型构造函数。...如果你使用递归模板实例化, 或者类型列表, 或者元函数, 又或者表达式模板, 或者依赖SFINAE, 或者sizeof trick 手段来检查函数是否重载, 那么这说明你模板用太多了, 这些模板太复杂了

1.1K30

【C++】STL 容器 - vector 动态数组容器 ③ ( vector 容器初始化 - 初始化列表 | vector 容器赋值 - assign 函数 swap 函数 )

vec; 使用 std::initializer_list 初始化列表 : 创建 vector 容器时 , 直接指定元素值 ; // 创建一个 vector 容器 , 元素类型是 int 类型...()); 2、使用 std::initializer_list 初始化列表 初始化 vector 容器 在之前有参构造函数中 , 介绍了几种 vector 初始化方式 , 这里 std::initializer_list...非常有用 ; 使用 std::initializer_list 初始化 vector 容器 , 可以先声明 std::initializer_list , 再使用已声明 std::initializer_list...使用 范围构造函数 从 vec1 容器中 复制元素到 vec2 容器 vector vec2(vec1.begin(), vec1.end()); // 4....使用 拷贝构造函数 创建 vec3 容器 // 将其初始化为 vec1 副本 vector vec3(vec1); // 5.

73410

C++ 11 新特性

,则推导类型函数返回值相同 如果表达式为左值或者被 () 包围,推导出来是表达式类型引用 骚操作: 返回类型后置 /** * @brief 阻塞等待 set_value * @return...,想放哪就放哪 委托构造函数 允许构造函数调用其他构造函数,建议在初始化列表中使用 public: explicit TestTask(std::string _name) : name_(std:...) { std::cout << _text << std::endl; } 继承构造函数 派生类可以直接使用基类构造函数: using qualifier::name; class TestTask...public: using TestTask::TestTask; }; 也可以通过这种方式来使用基类隐藏同名函数 std::initializer_list 一个轻量类模板,通过这个模板可以实现任意长度参数传递...(list); set_return({1, 2, 3, 4, 5}); return 0; } 同时也可以在构造函数使用 std::initializer_list 来传递多个实参 for

29610

Chapter 3: Moving to Modern C++

::initializer_lists和构造函数重载解析同时出现时容易造成错误调用 在调用构造函数时候,只要不涉及到std::initializer_list参数,括号和花括号初始化有相同含义...::initializer_list参数,在使用花括号初始化时,编译器会强烈地偏向于调用使用std::initializer_list参数重载构造函数 class Widget { public...construction 编译器非常偏向选择std::initializer_list构造函数,以至于即便最匹配std::initializer_list构造函数不能被调用,编译器也会优先选择它...只有当没有办法在花括号初始化参数类型std::initializer_list参数类型之间进行转换时,编译器才会重新选择正常构造函数 class Widget { public:...std::initializer_list构造函数时,此时调用空花括号初始化,编译器会解析为调用默认构造函数,而要解析成std::initializer_list构造函数,需要在花括号中嵌套一个空花括号进行初始化

1.8K60

初始化|这些年踩过

编译器有个特点,对于以花括号初始化方式则认为是统一初始化,如果构造函数中同样存在std::initializer_list为参数构造函数,那么则优先调用: class MyClass { public...{ MyClass obj{5, 1.0}; }; 我们可能期望MyClass obj{5, 1.0};调用第一个构造函数(以int和double作为参数构造函数),但由于存在以std::initializer_list...参数作为参数构造函数重载,因此该构造函数将是首选。...试想一下,如果不涉及缩小转换(例如,第二个构造函数接受 in std::initializer_list,则代码将使用第二个构造函数(在初始值设定项列表中int 5转换为double 5.0...)默默执行,而开发人员则认为它正在使用第一个构造函数,emm,后果不堪设想~~ 在上面提了,编译器会优先调用参数为std::initializer_list构造函数,但是有个例外: class MyClass

16810

C++中五花八门初始化规则

,默认值取决于变量类型和定义变量位置 无论何时只要类对象被创建就会执行构造函数,通过显式调用构造函数进行初始化被称为显式初始化,否则叫做隐式初始化 使用等号(=)初始化一个类变量执行是拷贝初始化,...类类型默认初始化 定义一个类变量但是没有指定初始值时,会使用默认构造函数来初始化,所以没有默认构造函数类不能执行默认初始化。...找不到合适构造函数 std::vector v3(10, "tomocat"); // 10个string元素vector, 每个string...对象 } int main() { foo(10); } 5. initializer_list形参 前面提到C++11支持所有类型初始化,对于类类型而言,虽然我们使用列表初始化它会自动调用匹配构造函数...C++11引入了std::initializer_list,允许构造函数或其他函数像参数一样使用初始化列表,这才真正意义上为类对象初始化与普通数组和 POD 初 始化方法提供了统一桥梁。

2.5K10

聊聊结构化绑定

<< ", " << kv.second << "]" << std::endl; } 但是这种方法仍远不完美,因为: •变量必须事先单独声明,其类型都需显式表示,无法自动推导;•对于默认构造函数执行零初始化类型...,零初始化过程是多余;•也许根本没有可用默认构造函数,如std::ofstream。...但是如何解释ri = 5;是合法呢? 这个问题需要系统地从头谈起。...还有一些语法细节,比如get名字查找、std::tuple_size没有value、explicit拷贝构造函数等,除非是深挖语法language lawyer,在实际开发中不必纠结(上面这一堆已经可以算...局限 以上代码示例应该已经囊括了所有类型结构化绑定应用,你能想象到其他语法都是错,包括但不限于: •用std::initializer_list初始化;因为std::initializer_list

25710

C++11『基础新特性』

其实就是当内置类型使用 { } 初始化时,实际上是在调用它构造函数进行构造 这就不奇怪了,无非就是让内置类型将 { } 也看做一种特殊构造构造 + 赋值 优化为 直接构造 我们可以通过一个简单...所以对于诸如 vector 这种自定义类型来说,需要把 列表初始化 视作一个类型,然后重载对这个类型参数构造函数就行了,于是 initializer_list 类就诞生了,这是一个模板类,大概长这样... 构造函数,这里简单举出几个例子 但凡重载了 initializer_list 构造函数,就能轻松使用 列表初始化 来初始化对象,如果没重载呢?... 构造函数就好了,比如这样 重载了 initializer_list 构造函数 ---- 位于 vector 类(自己模拟实现) // 供列表初始化调用 vector(const...直接告诉编译器:std::initializer_list::iterator 就是一个类型,并且 it 就是一个新建变量,此时就不会报错了 重载了 initializer_list 构造函数

21940
领券