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

C++那些事之SFINAE

在某些情况下,如果替换导致无效代码,编译器不应该抛出大量错误,而应该继续尝试其他可用的重载。SFINAE概念只是为“健全”的编译器保证这种“健全”的行为。...它只是尝试下一个重载。 再来回顾一下上述的简单理解:替换就是尝试用提供的类型或值替换模板参数的机制。在某些情况下,如果替换导致无效代码,编译器不应该抛出大量错误,而应该继续尝试其他可用的重载。...SFINAE概念只是为“健全”的编译器保证这种“健全”的行为。 所有的表达式都不会导致SFINAE。一个广泛的规则是说功能/方法主体之外的所有替代都是“安全的”。...您可能还想知道为什么它不能与继承一起使用。C ++中的继承和动态多态性是一个在运行时可用的概念,换句话说,就是编译器将不会拥有且无法猜测的数据!...您的编译器确实是个好人,不会遗忘任何分支,因此在这种情况下,obj必须同时具有serialize方法和to_string重载。

2.2K20

现代C++之SFINAE

在某些情况下,如果替换导致无效代码,编译器不应该抛出大量错误,而应该继续尝试其他可用的重载。SFINAE概念只是为“健全”的编译器保证这种“健全”的行为。...它只是尝试下一个重载。 再来回顾一下上述的简单理解:替换就是尝试用提供的类型或值替换模板参数的机制。在某些情况下,如果替换导致无效代码,编译器不应该抛出大量错误,而应该继续尝试其他可用的重载。...SFINAE概念只是为“健全”的编译器保证这种“健全”的行为。 所有的表达式都不会导致SFINAE。一个广泛的规则是说功能/方法主体之外的所有替代都是“安全的”。...您可能还想知道为什么它不能与继承一起使用。C ++中的继承和动态多态性是一个在运行时可用的概念,换句话说,就是编译器将不会拥有且无法猜测的数据!...您的编译器确实是个好人,不会遗忘任何分支,因此在这种情况下,obj必须同时具有serialize方法和to_string重载。

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

    【CMU15-445 FALL 2022】Project #1 - Buffer Pool

    当条件为true时,返回类型有效并启用函数模板; 当条件为false时,enable_if会导致编译器选择其他重载或者删除该函数模板。...如果我们尝试传递一个非数字类型(如字符串),则会导致编译错误,因为没有匹配的模板可用。...它允许根据常量表达式的结果来进行静态分支,以在编译时执行不同的代码路径。 constexpr if 在编译时进行条件分支,并且不满足条件的分支将不会被编译。...这意味着,不满足条件的代码块不会生成任何编译产物,包括生成的机器指令和相关的类型和符号。...在编译时,只有符合条件的代码块会被编译,而不满足条件的代码块不会产生任何代码。 constexpr if 的好处是它可以在编译时进行静态分支,避免了运行时的开销。

    31630

    Chapter 5: Rvalue References, Move Semantics, PF

    但是针对移动返回值的函数中,编译器不会执行RVO,因为这个函数不满足条件2,也就是返回值并不是局部对象本身,而是局部对象的引用,因此,编译器只能把w移动到返回值的位置。...Familiarize yourself with alternatives to overloading on universal references 三种简单的方法来代替对通用引用的重载 针对上面提到的...另一个问题是出现错误时,错误信息的易理解性,因为完美转发不会做参数类型是否符合最内层函数的类型,如果中间经过许多层转发,那么最后如果出现类型不匹配的错误,就会输出大量的错误信息,此时需要在适当的位置做一次预先判断...原因是: 直接调用f的时候,编译器可以看到在调用点传递的参数,以及函数f定义的参数类型,然后比较他们是否兼容,如果有必要,就执行隐式转换 通过完美转发间接调用f的时候,编译器就不会对在fwd...这种情况下出错的类型有: 编译器无法推导出一个类型:只要参数中有一个及以上无法推导出类型,就无法编译 编译器推到出错误的类型:要么是推导出来的类型使得无法编译,要么是推到出来的类型在重载函数情况下匹配到错误的函数调用

    5.1K40

    C++ Boost 库文档索引

    中已废除的库    什么库用何种编译器请看 [[http://www.boost.org/status/compiler_status.html][Compiler Status]]如何下载,建造,安装库请看.... config - 帮助 boost 库的开发者配置编译器特性;不打算提供给库用户使用. conversion - 各种类型间的转化,Numeric, polymorphic, 和 lexical casts..., 作者 Jeremy Siek 和 Chuck Allison. enable_if - 函数模板重载时的选择性包含, 作者 Jaakko Järvi, Jeremiah Willcock, 和 Andrew...al. concept check - 泛型编程的工具, 作者 Jeremy Siek. enable_if - 函数模板重载时的选择性包含, 作者 Jaakko Järvi, Jeremiah Willcock..., 作者 Ralf Grosse-Kunstleve and Jens Maurer. config - 帮助 boost 库的开发者配置编译器特性;不打算提供给库用户使用.

    1.6K10

    【C++11】消除重复, 提升代码质量---type_tratis

    1.2 判断两个类型之间的关系 traits同样提供了方法判断两个类型之间的关系,如:判断两个类型之间的相等或者继承关系traits主要提供了三种关系判断方法,主要是:is_same,is_base_of...,如果没有构造函数导致编译报错的问题; std::result_of原型如下: template 错误的,但是编译器会继续匹配,直到匹配到void Fun(T)后执行正确的函数,这种规则就是SFINAE;反之,如果一个模板函数都没有匹配到,则编译器会报如下错误...: error: no matching function for call to 'Fun(int)' std::enable_if实现了根据条件选择重载函数的规则,其原型如下: template编译期间检查模板参数是否有效。使用std::enable_if可以实现一个强大的重载机制,充分利用可以减少或者消除圈的复杂度。如:根据不同的数据基本类型转换为string进行输出。

    1.7K10

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

    此外,缺省参数会造成臃肿的代码,毕竟它们在每一个调用点(call site)都有重复(acgtyrant 注:我猜可能是因为调用函数的代码表面上看来省去了不少参数,但编译器在编译时还是会在每一个调用代码里统统补上所有默认实参信息...,造成大量的重复)。...虽然可以用工厂函数(acgtyrant 注:factory function, 出自 C++ 的一种设计模式,即「简单工厂模式」)或 Init() 方法代替异常, 但是前者要求在堆栈分配内存,后者会导致刚创建的实例处于...使用流时容易造成的这类错误: cout << this; // 输出地址 cout << *this; // 输出值 由于 重载, 编译器不会报错....缺点: 若过早把变量优化成 constexpr 变量,将来又要把它改为常规变量时,挺麻烦的;当前对constexpr函数和构造函数中允许的限制可能会导致这些定义中解决的方法模糊。

    1.2K30

    C ++ 中不容忽视的 25 个 API 错误设计!

    重要的是,这些默认值在.cpp文件中指定,并且不在.h文件中公开。因此,API的更高版本可以更改这些值,而不会对公共接口产生任何影响。 补充说明: 不需要将所有默认参数实例转换为重载方法。...错误#14:不避免不必要的include头文件 为什么这是一个错误? 不必要的头文件可以明显增加编译时间。...你可以定义方法的新重载版本,而不需要向现有方法中添加参数。这可以确保原始符号继续存在,但也提供了较新的调用约定。在.cpp文件中,可以通过简单地调用新的重载方法来实现旧方法。...错误#20:向已发布的类API添加纯虚方法 为什么这是一个错误?...,因为现在他们必须为这个新方法定义一个实现,否则他们的派生类将不具体,他们的代码也不会编译。

    1.6K20

    C++ 特性使用建议

    3.函数重载 (1)仅在输入参数类型不同、功能相同时使用重载函数(含构造函数),当使用具有默认形参值的函数(方法)重载的形式时,需要注意防止二义性。...(4)异常是处理构造函数失败的唯一途径,虽然可以用工厂模式产生对象或 Init() 方法代替异常,但是前者要求在堆栈分配内存,后者会导致刚创建的实例处于 ”无效“ 状态。...千万别用宏进行条件编译,会令测试更加痛苦 ,当然使用条件宏防止头文件重复包含是个特例。...(2)模板编程经常会导致编译出错的信息非常不友好:在代码出错的时候,即使这个接口非常的简单,模板内部复杂的实现细节也会在出错信息显示。导致这个编译出错信息看起来非常难以理解。...因为这些出错信息也是你的接口的一部分,所以你的代码必须调整到这些错误信息在用户看起来应该是非常容易理解,并且用户很容易知道如何修改这些错误 23.Boost 库 只使用 Boost 中被认可的库。

    1.7K20

    属性“__attribute__”在Objective-C中的应用

    ,有时候,我们定义了一个类,但是不希望再有其他的类继承于它,即我们要定义的类本身就是一个最终类,不能再被继承,这是就可以使用这个属性来修饰,如果有类继承它会报编译错误,例如: ?...8. objc_requires_super       这个属性用来修饰Objective-C中父类的方法,如果子类进行了重写,在重写的方法中没有调用父类方法,则会进行编译器提示。...9. enable_if       enable_if提供了一种方式对函数的参数进行校验,不满足校验规则的参数传递将在编译时报错,使得函数的使用更加安全,例如: ?...这种编译时即可对函数参数进行检查的机制可以避免写很多运行时的代码,并且比运行时更高效的规避错误。...overliadable属性可以指定某个函数为可重载,这样既可定义名字相关参数不同的多个C函数,在调用时,编译器会根据传入的参数类型自行判断具体调用哪个函数,如下: ?

    2.4K20

    C++ 智能指针详解

    所有智能指针都重载了“operator->”操作符,直接返回对象的引用,用以操作对象。访问智能指针原来的方法则使用“.”操作符。 访问智能指针包含的裸指针则可以用 get() 函数。...(2)    记住 release() 函数不会释放对象,仅仅归还所有权。 (3)    std::auto_ptr 最好不要当成参数传递(读者可以自行写代码确定为什么不能)。... error: scoped_ptr 没有重载 operator=,不会导致所有权转移   } } 首先,我们可以看到,boost::scoped_ptr 也可以像 auto_ptr 一样正常使用。...但其没有release() 函数,不会导致先前的内存泄露问题。...// 编译 error,同上,没有重载 operator=       }     } boost::scoped_array 的使用跟 boost::scoped_ptr 差不多,不支持复制,并且初始化的时候需要使用动态数组

    2K10

    C++特性使用建议

    3.函数重载 (1)仅在输入参数类型不同、功能相同时使用重载函数(含构造函数),当使用具有默认形参值的函数(方法)重载的形式时,需要注意防止二义性。...(4)异常是处理构造函数失败的唯一途径,虽然可以用工厂模式产生对象或 Init() 方法代替异常,但是前者要求在堆栈分配内存,后者会导致刚创建的实例处于 ”无效“ 状态。...宏意味着你和编译器看到的代码是不同的。这可能会导致异常行为,尤其因为宏具有全局作用域。值得庆幸的是,C++ 中,宏不像在 C 中那么必不可少。以往用宏展开性能关键的代码,现在可以用内联函数替代。...(2)模板编程经常会导致编译出错的信息非常不友好:在代码出错的时候,即使这个接口非常的简单,模板内部复杂的实现细节也会在出错信息显示。导致这个编译出错信息看起来非常难以理解。...因为这些出错信息也是你的接口的一部分,所以你的代码必须调整到这些错误信息在用户看起来应该是非常容易理解,并且用户很容易知道如何修改这些错误 23.Boost 库 只使用 Boost 中被认可的库。

    1.9K30

    C++ 智能指针

    所有智能指针都重载了“operator->”操作符,直接返回对象的引用,用以操作对象。访问智能指针原来的方法则使用“.”操作符。 访问智能指针包含的裸指针则可以用 get() 函数。...(2) 记住 release() 函数不会释放对象,仅仅归还所有权。 (3) std::auto_ptr 最好不要当成参数传递(读者可以自行写代码确定为什么不能)。...error: scoped_ptr 没有重载 operator=,不会导致所有权转移 } } 首先,我们可以看到,boost::scoped_ptr 也可以像 auto_ptr 一样正常使用。...但其没有 release() 函数,不会导致先前的内存泄露问题。...// 编译 error,同上,没有重载 operator= } } boost::scoped_array 的使用跟 boost::scoped_ptr 差不多,不支持复制,并且初始化的时候需要使用动态数组

    1K40

    Signals-The Boost C++ Libraries

    该函数的签名与作为模板参数传递的签名相匹配。 方括号为空,因为void()不需要任何参数。 调用s会导致触发器,该触发器又执行先前与connect()关联的lambda函数。...\n"; }); s(); } boost::signals2::signal允许您通过重复调用connect()将多个功能分配给特定信号。...默认情况下,仅返回所有关联函数的最后一个返回值。 请注意,s()不会直接返回最后一个调用函数的结果。返回类型为boost::optional的对象,取消引用后将返回数字2。...触发与任何功能均不相关的信号不会产生任何返回值。因此,在这种情况下,boost::optional允许Boost.Signals2返回一个空对象。第21章介绍了boost::optional。...boost::signals2::signal期望组合器定义一个称为result_type的类型,该类型表示operato()返回的值的类型。由于标准算法未定义此类型,因此编译器将报告错误。

    1.3K40

    C++ 学习笔记

    C++17 中, 无链接属性也可 4.内部链接:如果一个名称对编译单元(.cpp)来说是局部的,在链接的时候其他的编译单元无法链接到它且不会与其它编译单元(.cpp)中的同样的名称相冲突。...b.若表达式结果为 false,根据替换失败并非错误的原则,包含 std::enable_if 的模板将会被忽略。...if 除了前面介绍的忽略模板的方法,c++17 还提供了编译期的条件判断语法 if constexpr(...)。...9.2 模板和 inline 函数模板全特化后和普通函数相同,但函数模板一般定义在头文件中,为了避免在多个模块 include 时出现重复定义的错误,一般将全特化后的函数模板定义为 inline。...空基类优化:在空类作为基类时,如果为它不分配内存不会导致它存储到其他同类型对象或者子类型对象的相同地址上,则可以不分配。

    6.8K63

    Golang对比C++的开发环境的变化

    , 因为库的不同, 在表现形式上会有各式各样的差异, 为了减少这种差异, 除了语言本身之外, 还需要定义一些依赖相关的规范, 来让代码变得一致 比如库 boost, 但是 boost 也有自己的版本,..., 对于 Golang, 不会出现 boost 这种东西 用户的学习成本也低一些, 拿来就用 1.1.3 语言高级特性 相比 C++, Golang 几乎可以将所有精力放在业务上, 而不用担心语言自身存在的问题....h 和 库文件分离导致的可能的不一致, 可能是库文件版本比较多, 以及操作系统的差异带来的 core 和无法运行, 为了防止重复引入, 还有一些 ifdefine 宏, pragma once 这些语法...而且, 以本地文件为依赖, 也会出现文件重复的情况, 重复 + 自定义需求, 就会导致文件的不一致, 这也是我们的文件里, 不同项目之间大量代码重复的原因之一 Golang (除了 cgo 以外),...的代码复用相对容易一些, 不会因为不方便编译的原因, 自己下载库修改完, 不 merge 造成不一致, 同时, 以 包 为隔离, 也容易使得代码的模块划分相对好做, 这些特性, 使得 Golang 的

    2.8K80

    iOS 编译器__Attribute__的入门指南

    这是一个可以给对象或函数声明特性的编译器指令,目的是让编译器做更多的错误检查和优化。.../* OC中可以是用 #param mark - xxxx swift使用 #MARK - xxxxx */ // 在父类中某个被重写的方法上添加这个,编译器会提醒子类的重写方法中调用...用来添加一些函数调用时需要满足的条件,会在编译时发出警告或者提醒 //不会发出运行时的的警告。...exit() 函数是 _Noreturn 函数的一个示例,一旦调用exit() 它不会往下执行了。 和 void 返回类型不同的是,void 类型的函数再执行完毕后返回主调函数,只是它不提供返回值。...,deprecated=10.6,obsoleted=10.7))); // 这个参数列表有没有感觉像 @#available() 2、C 中重载一个C++函数 // 在C中重载一个C++函数,C中的函数重载是使用可重载属性引入的

    98020
    领券