首页
学习
活动
专区
工具
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.7K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【重学 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,以方便使用初始化列表语法进行隐式转换。同类型的扩展类,为了避免差异化,隐式转换会更合适。

    25000

    【C++11】统一的 {} 列表初始化

    为了避免类型收缩转换带来的问题,建议在转换时进行类型检查,并使用合适的转换函数(例如 static_cast 或 dynamic_cast)来确保转换的正确性。...构造出一个对象然后再初始化,这个下面会讲 Point p{ 1, 2 }; // 使用new和上面的p就不太一样了,会去调用构造函数初始化 // 若没有自己写的构造函数...它可以将你放入 {} 中的元素按照你要的类型 T 生成一个 initializer_list 对象,接着还有重要的一步,就是如 vector、list 等容器中,C++11 已经添加了新的构造函数参数:...以 initializer_list 为参数的构造函数,这样子的话我们就能运用 {} 来初始化容器了! ​...).name() << endl; return 0; } // 运行结果 class std::initializer_list ​ 那么我们如何在模拟实现 vector、list 等容器的时候增加

    8900

    第七章 函数

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

    19530

    【c++11】列表初始化与声明

    ,这里会调用构造函数初始化 Date d2{ 2025, 1, 2 }; Date d3 = { 2025, 1, 3 }; return 0; } std::initializer_list std...使用示例 (1)用于函数参数 一个函数可以接受 std::initializer_list 参数,从而支持传入多个值作为初始化列表: #include initializer_list> #include...可以使用 std::initializer_list 构造一个类,使其接受列表初始化: #include initializer_list> #include #include...::cout std::endl; // 输出 10 return 0; } (2)与 auto 配合使用 虽然 auto 也能推导类型,但有时需要明确指定某个表达式的类型,decltype...std::cout std::endl; // 输出 5.5 return 0; } (3)用在函数返回类型 在函数返回类型中,可以使用 decltype 推导返回值的类型,特别是在泛型编程中非常有用

    13810

    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*作为通用类型的场景。

    3.4K10

    现代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属性的未命名类型,我们需要弄清楚如何使用它们!

    3K20

    列表初始化:轻量级对象initializer_list

    C++98中的初始化方式 在C++98中,数组和聚合类型(如结构体)可以使用大括号{}进行初始化,但基本类型和自定义类对象通常不能直接使用{}初始化,需要使用构造函数或赋值操作。...基本类型和自定义类的初始化 在C++98中,基本类型的初始化不能使用{},需要使用赋值或构造函数。...自定义类型的初始化 除了标准容器,用户自定义的类也可以通过定义接受std::initializer_list的构造函数,来支持列表初始化。...::initializer_list的构造函数:在自定义类MyClass中,定义了一个构造函数,接受std::initializer_list类型的参数。...容器对std::initializer_list的支持 构造函数 标准容器都增加了接受std::initializer_list的构造函数。

    28610

    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.2K30

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

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

    20520

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

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

    2K20

    【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_list的vector构造函数】不同原理 C++11中新增的关于...{}用法 (传送门):具体对象是下面代码中Point, 直接调用两个参数的构造 – 隐式类型转换 我们vector容器构造函数的参数是std::initializer_list, 这里是调用initializer_list...-- 隐式类型转换 return 0; } 四.std::initializer_list的文档传送门 initializer_list 文档传送门

    41010

    【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.

    3.2K10

    C++ 11 新特性

    ,则推导的类型和函数返回值相同 如果表达式为左值或者被 () 包围,推导出来的是表达式类型的引用 骚操作: 返回类型后置 /** * @brief 阻塞等待 set_value * @return...,想放哪就放哪 委托构造函数 允许构造函数调用其他构造函数,建议在初始化列表中使用 public: explicit TestTask(std::string _name) : name_(std:...) { std::cout 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

    31510

    【C++】语法简化和增强,C++11都做了什么?

    容器{}初始化可以有任意多个参数 1.2 std::initializer_list std::initializer_list是C++11引入的一种特殊类型,它提供了一种简洁、直观的方式来初始化容器或数组...,以及作为函数(特别是构造函数)的参数来接受多个同类型的值。...作为函数参数,特别是当函数需要处理多个同类型参数时,使用std::initializer_list可以使函数接口更加简洁和灵活。...| 列表初始化和initializer_list的区别和联系: 区别: 列表初始化是一种初始化方式,而initializer_list是一种类型 列表初始化使用大括号{}来包围初始化器的值,而initializer_list...则是一个模板类,用于接收这些值 联系: 当使用列表初始化语法时,编译器会生成一个std::initializer_list对象来存储初始化列表中的元素 类的构造函数可以重载以接受一个std::initializer_list

    7610

    初始化|这些年踩过的坑

    编译器有个特点,对于以花括号初始化的方式则认为是统一初始化,如果构造函数中同样存在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

    23710

    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
    领券