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

C++那些事之SFINAE

如您所见,在序列化过程中,很容易检查对象是否具有属性并查询该属性的类型。在我们的例子中,它允许我们使用serialize方法(如果可用),否则返回到更通用的方法str。功能强大,不是吗?...根据名称找出所有适用的函数和函数模板对于适用的函数模板,要根据实际情况对模板形参进行替换; 替换过程中如果发生错误,这个模板会被丢弃 在上面两步生成的可行函数集合中,编译器会寻找一个最佳匹配,产生对该函数的调用...如果我们能处理一些编译时整数,我们不能做一些编译时比较吗? 答案是:绝对是的(当然可以比较),我亲爱的读者!...有些人甚至决定为像我这样的下一代c++程序员设计一个新的标准!这个标准不仅可以减轻TMP的麻烦(模板元编程的副作用),而且在第一个十年就可以使用,因此它的代码名为c++ 0x。...Lambdas被实现为一个具有新创建的未命名类型(也称为闭包类型)的对象。如果一个lambda有一些自动参数,它的“函子操作符”操作符()将被简单地模板化。

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

    深入探索 C++17 特征变量模板 (xxx_v)

    在C++的持续演进中,C++17带来了许多令人眼前一亮的特性,其中特征变量模板(xxx_v)以其简洁高效的特性,在类型处理领域发挥着重要作用。..." std::is_rvalue_reference_v std::endl; return 0;}四、在模板元编程中的关键作用在模板元编程中,特征变量模板...通过与std::enable_if结合,可以实现条件编译,增强代码的健壮性。...,确保只有当T和U都是算术类型时,add函数模板才会被实例化,有效避免了类型不匹配导致的错误。...五、总结与展望C++17特征变量模板(xxx_v)为C++开发者提供了更为便捷的类型处理方式,无论是在基础类型判断,还是复杂的模板元编程中,都展现出了强大的优势。

    8210

    现代C++之SFINAE

    如您所见,在序列化过程中,很容易检查对象是否具有属性并查询该属性的类型。在我们的例子中,它允许我们使用serialize方法(如果可用),否则返回到更通用的方法str。功能强大,不是吗?...根据名称找出所有适用的函数和函数模板对于适用的函数模板,要根据实际情况对模板形参进行替换; 替换过程中如果发生错误,这个模板会被丢弃 在上面两步生成的可行函数集合中,编译器会寻找一个最佳匹配,产生对该函数的调用...如果我们能处理一些编译时整数,我们不能做一些编译时比较吗? 答案是:绝对是的(当然可以比较),我亲爱的读者!...有些人甚至决定为像我这样的下一代c++程序员设计一个新的标准!这个标准不仅可以减轻TMP的麻烦(模板元编程的副作用),而且在第一个十年就可以使用,因此它的代码名为c++ 0x。...Lambdas被实现为一个具有新创建的未命名类型(也称为闭包类型)的对象。如果一个lambda有一些自动参数,它的“函子操作符”操作符()将被简单地模板化。

    3K20

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

    什么是LRU? 是一种缓存淘汰机制,全称为Least Recently Used,即最近最少使用算法。 当缓存满了的时候,会将当前最久没被使用过的元素从缓存中踢出,给新进来的数据腾出空间。...); // 调用第二个printNumber模板 printNumber("Hello"); // 错误,没有匹配的模板可用 return 0; } 在上面的示例中,我们定义了两个重载的函数模板...如果我们尝试传递一个非数字类型(如字符串),则会导致编译错误,因为没有匹配的模板可用。...enable_if还可以与其他模板元编程技术结合使用,例如std::enable_if_t、std::conditional等,以实现更复杂的条件选择和类型推导。...enable if 是一个模板元编程工具,使用 typename std::enable_if::type 的形式将其应用于模板参数或函数返回类型。

    31630

    现代C++之SFINAE应用(小工具编写)

    本文的代码是我修改自原作者代码,我的代码与原作者地址如下: ?...is_pair_v = is_pair::value; 首先是一个模板结构体,紧接着是模板偏特化,分别继承了false_type、true_type,而继承之后就拥有了value属性,根据C++...若可以直接输出,那就调用系统的输出了,否则调用后面自己写的,因此后面目标变为:针对没有输出函数的容器调用自己编写的输出函数。...3.针对没有输出函数的容器处理 通过enable_if_t限定调用是针对没有输出函数的容器,内部逻辑很简单,第一次只输出元素,后面就输出,与元素,也就是用,分割元素,最后就是比较重要的output_element...// 针对没有输出函数的容器处理 template<typename T, typename = std::enable_if_t<!

    1.2K20

    未来已来:从SFINAE到concepts

    这是一种 C++ 中的编译期技术,用于在模板实例化过程中,当尝试进行模板参数的替换时,如果出现了替换失败(通常是由于找不到相应的成员函数、操作符等),不会导致编译错误,而是会选择其他可行的模板特化。...它的核心思想是,如果在模板参数的替换中遇到了错误,编译器不应该报错,而是应该简单地将这个特化从候选列表中移除。这样,即使部分模板特化失败,编译仍然可以继续进行,选择其他可行的特化。...std::enable_if 就是利用了 SFNIAE 的概念,通过在模板参数替换失败时移除特化,实现了在编译期间的条件选择。...这种特性使得在模板中可以编写更加直观和灵活的代码,而不必依赖于模板元编程中的繁琐技巧,同时可以避免生成不必要的代码。...在前面的例子中,我们无非是通过各种方式来约束参数,使得满足某个条件的参数调用一个模板函数,而不满足的则使用另外一个模板函数。这种方式在C++20用的更为广泛,称之为约束模板参数。

    25410

    浅谈 C++ 元编程

    例如,C++ 14 中的 别名模板 std::enable_if_t 等价于 typename std::enable_if::type。...假设是脚本语言,这段代码是没有问题的:因为脚本语言没有编译的概念,所有函数的绑定都在 运行时 完成;而静态语言的函数绑定是在 编译时 完成的。...函数 Sum 有两个重载:一个是对没有函数参数的情况,一个是对函数参数个数至少为 1 的情况。和定长模板的迭代类似,这里也是通过 递归 调用实现参数遍历。...元编程的主要难点 由于 C++ 语言设计层面上没有专门考虑元编程的相关问题,所以实际元编程难度较大。元编程的难点主要有四类:复杂性、实例化错误、代码膨胀、调试模板。...4.2 实例化错误 模板的实例化 和 函数的绑定 不同:在编译前,前者对传入的参数是什么,没有太多的限制;而后者则根据函数的声明,确定了应该传入参数的类型。

    3.1K61

    C++ 学习笔记

    b.若表达式结果为 false,根据替换失败并非错误的原则,包含 std::enable_if 的模板将会被忽略。...2.c++14 提供了别名模板技术(见 2.8 节),可以用 std::enable_if_t代替 std::enable_if::type. 3.若不想在声明中使用 std::enable_if...一种简单用法是 6.3 6.4 中的 std::enable_if;对于上例,则可以采用 auto + 尾后返回的方式,使得在替换时就知道 T 中必须含有 size 成员的限制。...函数模板可以有 c++链接,但不能有 C 链接。 函数模板一般具有外部链接,除非是 static 或定义在未命名的命名空间中。...,名字空间是名字空间是枚举声明所在的名字空间,对于类成员,关联类是枚举所在的类 (4)对于 class(包含联合类型),关联类包括该类本身,他的外围类,直接基类,间接基类。

    6.8K63

    性能优化利器之constexpr

    今天,聊聊在升级过程中的一个比较重要的优化点-编译期优化。 概述 说明符constexpr是自C++11引入,我相信很多人跟我一样,在第一次接触这个的时候,会很容易和const混淆。...在上面示例2中,通过汇编代码发现其是在运行期求值,那么有没有办法在编译期求值呢?...自C++17起,引入了if constexpr语句,在本节中,将借助SFINAE 和 std::enable_if来实现一个简单的Square功能,最后借助if constexpr对代码进行优化(如果对...在上述代码中,为了编译成功,我们引入了两个Square()模板函数借助std::enable_if来实现,代码上多少有点冗余,在这个时候,本节的主角if constexpr 出场,完整代码如下: #include...我们借助一个Square()函数模板以及更加符合编码习惯的if语句就能解决上面的问题,且比使用std::enable_if方式更为优雅和符合阅读习惯,进而提高代码的可阅读性。

    42210

    C++11:unique_ptr 自己定义类似make_shared的make_unique模板函数

    模板参数中增加了一个常量参数ZERO,用于编译期判断。...用到了名为std::enable_if的type_traits,它类似一个if语句,判断ZERO,当ZERO为true时编译器选择第一个版本的函数,反之选择第二个。...enable_if是C++11头文件中的一个类,关于enable_if的用法详细说明参见: class template std::enable_if...其实我是写完上面的代码在VS2015下编译时,报了个错, 我这才发现,VS2015已经提供了make_unique 以下是来自VS2015的头文件中make_unique...的实现代码,代码中创建普通对象和数组对象的函数名都是make_unique,与我写的版本不一样,而且微软的版本中也没有区分是否在初始化数组,一律初始化为0。

    1.2K20

    MSVC std::unique_ptr 源码解析

    // destructor // block end 比较重要的一点是 std::unique_ptr 删除了拷贝构造,所有它对对象的所有权是独享的,你没有办法直接将 std::unique_ptr..._Compressed_pair _Compressed_pair 是 std::unique_ptr 内部用于存储 deleter 和裸指针的工具,从字面意思来看,它实现的功能和 std::pair...unique_ptr; 这里的模板参数 _Ty 是保存的对象类型,_Dx 是删除器类型,默认为 default_delete,下面是具体的定义: template struct..._Get_deleter_pointer_type 决定,我们可以发现它有两个定义,前者是默认定义,当删除器中没有定义 pointer 时会 fallback 到这个定义,如果删除器定义了 pointer...总结 std::unique_ptr 有两个定义,分别针对普通类型和数组类型 std::unique_ptr 第二个模板参数是删除器,不传递的情况下使用的是 default_delete std::unique_ptr

    1.6K10

    LLVM Pass 其一:PassManager

    std::vectorstd::unique_ptr> Passes; } 关于声明中要注意的有一点:上一期我们提到继承了PassInfoMixin的类我们就可以视为是一个...Pass(从语法角度来说),也就是说PassManager本身也是一个Pass 接着来讲一下模板参数 IRUnit 对于每个Pass有其作用的范围,有的是作用在函数上的,有的是作用到一个CFG中的 还记得上期里讲到新...我最初的想法是被保存的Analysis,理解上更偏向于是被缓存了的Pass,但是仔细一想我觉得换一种说法来描述PreserveAnalyses就好理解了:PreserveAnalyses中记录的是在这之后能够正确获取结果的...也就是说跑完PassManager这个“Pass”之后所有的Analysis依然是能够正确获取的 在编写自己Pass的时候要手动指定使得哪些Analysis失效,原因是因为你在这个Pass里面做过了修改并且没有更新...addPass 还是熟悉的enable_if,主要是根据参数是RepeatedPass还是普通Pass以及PassT是否满足HasRunOnLoopT产生了四种情况 template <typename

    1.8K10

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

    false有疑问,其实const int *是说指针是一个常量,但是指向的内存地址中的值是可以变化的,并不是常量。...D: true 1.4 获取可调用对象返回类型的traits std::result_of可以在编译器获取可调对象的返回类型,帮助解决编码过程中如下问题: 函数入参为模板参数,不能直接确定函数返回类型...{ Fun(1); return 0; } 程序运行为最终会匹配到第二个模板函数,但是在实际的匹配过程中,当匹配到void Fun(T*)时用整数对T*进行替换是错误的,但是编译器会继续匹配,直到匹配到...void Fun(T)后执行正确的函数,这种规则就是SFINAE;反之,如果一个模板函数都没有匹配到,则编译器会报如下错误: error: no matching function for call to...因此,它可以在编译期间检查模板参数是否有效。使用std::enable_if可以实现一个强大的重载机制,充分利用可以减少或者消除圈的复杂度。如:根据不同的数据基本类型转换为string进行输出。

    1.7K10

    C++17逻辑魔法:std::conjunction、std::disjunction 与 std::negati剖析

    一、std::conjunction:逻辑与的力量1.1 定义与概念在 C++17 中,std::conjunction 是一个用于类型层面逻辑与操作的模板。...>::value 的便捷写法)来判断模板参数包 Ts 中的所有类型是否都是整数类型。std::is_integral 是 C++ 标准库提供的类型特性模板,用于判断类型 Ts 是否为整数类型。...最后,在 calculate 函数模板中,使用 std::enable_if_t 结合 is_valid_numeric_type 来确保只有满足条件的类型才能实例化该函数模板。...4.2 函数模板的条件启用std::enable_if_t 是 C++ 标准库中用于条件编译的一个重要工具,它常常与 std::conjunction、std::disjunction 和 std::negation...如果传入的是整数类型或字符串类型,对应的函数模板会被实例化并执行;如果传入的是其他类型,如 double,则会导致编译错误,因为不满足 std::enable_if_t 的条件 。

    10410

    Chapter 5: Rvalue References, Move Semantics, PF

    另一种高级做法,限制(constraining)采用通用应用的模板 为了在特定的条件下,让函数调用发生在应该发生的位置上,我们需要根据条件来启用/禁用模板匹配,方式是std::enable_if,如果内部判断条件为...std::array没有这个特性,因为它把内容存储在自身空间中,即便存储的内容对象本身支持移动操作,且移动操作比拷贝要快,而且std::array也支持移动操作,但对于std::array来说,移动操作和拷贝操作代价一样...同样,在将MinVals传递到模板函数fwd中时,这个模板参数是一个引用,它本质上和指针是一样,只不过是一个会自动解引用的指针,那么在编译该函数时就需要对MinVals进行取地址,而MinVals此时并没有定义...,也就没有内存空间。...但是上述行为实际上是依赖于编译器的,安全的做法是在cpp文件中定义一次MinVals constexpr std::size_t Widget::MinVals; 重载函数名和模板名的自动推导 一个模板函数接收重载函数作为参数时

    5.1K40

    C++ enable_shared_from_this 具体实现

    的别名构造函数(The aliasing constructor),意思是说,共享 r 参数的引用计数, 但是 .get() 返回的是 ptr 指针。...这个就是模板元编程的特点,编译器生成模版函数和我们手写函数的逻辑完全不同,我们手写的函数不合法,编译器就会报错,但是如果编译器生成出来的发现不合法,编译器就会不生成这个函数。..._NOEXCEPT {} 对于第一个问题,就是 enable_if 起的作用: enable_if::type 的意思是说,如果bool值为true,enable_if 返回的就是第二个模版参数...类型T, 如果为false,返回空(不是void,而是什么也没有) 那么看下: enable_if的意思就是说,如果传入的裸指针类型是继承自 enable_shared_from_this 的,那么 返回 void 类型,否则返回空,让 __enable_weak_this 函数替换失败

    1.1K30

    C++20初体验——concepts

    有些资料中的标准库concept是帕斯卡命名(PascalCase)的,因为最初的concept提案中是这样写的,原因可能是为了让它看起来属于新的C++20,或是与模板参数列表中类型大写的习惯一致。...函数模板与类模板的约束是类似的,只有满足约束时模板才能实例化;对于成员函数的约束,如果它作用于模板类的模板参数,当约束不满足时,并不是类模板不能被实例化,而是实例化后的模板类没有这个成员函数: #include...模板升级 面向过程、基于对象、面向对象、泛型和函数式这几个编程范式是逐渐加入C++的。起初,C++并没有模板,直到1990年。...);唯独第三条没有解决,导致冗长的模板错误,并且衍生出以SFINAE为代表的一些奇技淫巧。...的模板类型发生错误,根据SFINAE,该重载被忽略;与此同时第二个是可用的。

    1.4K10

    C++11:模板实现opencl向量类型的简单运算符重载及length,distance函数

    ,但c/c++以及opencl的API本身并没有提供对这些向量类型的一般运算支持。...如果能像模板内核代码一样,为向量运算符提供简单的向量运算功能,就可以大大简化这些代码。 利用C++的模板计算函数,可以实现上面的功能。...(实现其他的运算符和函数也是差不多的代码,因为我暂时不需要就没有继续写下去)。...代码开始有两个很长的模板函数cl_vector_type和is_cl_vector,所有的其他函数模板都要用到这两个模板函数: cl_vector_type用于构造一个指定元素类型和长度的opencl...is_cl_vector则用于判断一个类型是否是opencl的向量类型,如果是value为true,size中保存向量长度,type则是向量元素的类型。

    1.7K10

    C++反射:深入浅出剖析ponder库实现机制!

    导语 | 给静态语言添加动态特性,似乎是C++社区一件大家乐见其成的事情,轮子也非常多,我们不一一列举前辈们造的各种流派的轮子了,主要还是结合我们框架用到的C++反射实现,结合C++的新特性,来系统的拆解目前框架中的反射实现...另外一点是meta function没有像C#那样直接给出Invoke方法,这个是因为目前的实现针对不同使用场合,类型擦除的函数是不同的,比如对于lua,类型擦除的函数原型是lua_CFunction。...对于C++,则是: std::function; 不同场合不同统一类型的好处是不需要Wrapper,没有额外的性能开销,但同时也会导致外围的使用变麻烦,这里可能需要根据项目实际情况做一定的调整...DispatchType: 配合std::function使用,作为std::function的模板参数,这样就可以构造一个与原始Function类型匹配的std::function对象了。...DispatchType: 配合std::function一起使用,作为std::function的模板参数,这样就可以构造一个与原始Function类型匹配的函数对象了。

    1.6K20
    领券