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

声明使用`enable_if`专门化的类模板时,为什么需要`void`

在声明使用enable_if专门化的类模板时,需要使用void的原因是为了指定特定条件下的模板实例化结果为空类型。enable_if是一个模板元函数,用于在编译时根据条件选择是否启用特定的模板实例化。

enable_if通常与模板的SFINAE(Substitution Failure Is Not An Error)机制一起使用,用于在编译时根据条件对模板进行选择性实例化。当条件为真时,enable_if的第一个模板参数为true_type,此时模板实例化成功;当条件为假时,enable_if的第一个模板参数为false_type,此时模板实例化失败,但不会导致编译错误。

在声明使用enable_if专门化的类模板时,需要使用void作为enable_if的第一个模板参数,以指定特定条件下的模板实例化结果为空类型。这样可以在编译时根据条件选择是否启用特定的模板实例化,并且不会产生实际的类型。

以下是一个示例代码:

代码语言:txt
复制
#include <type_traits>

template <typename T, typename = void>
class MyClass
{
    // 当条件为真时,此模板实例化成功
};

template <typename T>
class MyClass<T, typename std::enable_if<std::is_integral<T>::value>::type>
{
    // 当 T 为整数类型时,此模板实例化成功
};

int main()
{
    MyClass<int> obj1;  // 第二个模板实例化成功
    MyClass<double> obj2;  // 第一个模板实例化成功
}

在上述示例中,MyClass是一个类模板,根据条件选择性实例化。当模板参数T为整数类型时,使用enable_if的专门化模板进行实例化,否则使用默认的模板进行实例化。通过使用void作为enable_if的第一个模板参数,可以指定特定条件下的模板实例化结果为空类型。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【Groovy】编译元编程 ( 编译元编程引入 | 声明需要编译处理 | 分析 Groovy AST 语法树 )

文章目录 一、编译元编程引入 二、声明需要编译处理 三、分析 Groovy AST 语法树 一、编译元编程引入 ---- 在之前 " 【Groovy】MOP 元对象协议与元编程 " 系列博客中..., 都是围绕 MetaClass " 运行时元编程 " , 其在运行时才进行相关元编程操作 , 如方法注入 , 方法委托等 ; 在编译也可以进行元编程操作 ; 在 Java 和 Android...中 , 可以使用 注解处理器 AbstractProcessor 实现 APT 编译技术 , 参考 【Android APT】 专栏 ; 在 Groovy 中实现编译技术 , 类似于 Java...中编译技术 ; 二、声明需要编译处理 ---- 声明一个 Student , 在其中定义成员变量和成员方法 ; 之后需要在编译处理该类 ; class Student{ def...选项 , 分析上述 Student AST 语法树 ; 分析结果在 Groovy AST Browser 对话框中显示 ;

52140

C语言为什么需要include就能使用里面声明函数?

有人问:C语言为什么需要include就能使用里面声明函数?这是一个看起来非常简单问题,但是很多初学者,甚至学了很久的人都可能没有搞明白。 为什么包含即可用?...所以实际上,你只是在你.c中声明了这些函数,既然声明了,那么你就可以使用。但是你要想真正用到它,还需要找到它定义。这是在链接阶段做事情。...(-lm表示需要链接math库) 当然了,对于C++,使用pow函数不用链接math库也是可以为什么呢?请移步这里《C++为什么需要单独链接math库?》。 不包含可以用吗?...那么一定要包含才可以使用吗?并非如此。前面说过了,包含不过是使用里面的声明,既然如何,我们自己声明怎么样?....); int main(void) { printf("hello,编程珠玑\n"); return 0 ; } 同样可以好好运行,因为你可以自己声明或者指定为外部声明

1.3K20
  • Integer以及包装使用值比较需要注意问题

    看以下代码以及执行结果: public static void main(String[] args) { Integer a = 2; Integer b =...结果在判断c是否与d相等 出现了false。 这是因为Integer源码中有一个IntegerCache,这一个私有的内部类。这个缓存了-128到 127之间数字包装。...需要记住它把一些数字包装提前缓存了,如果判断成立就把缓存中那个包装返回,如果不则new一个新。 ? 可以看到判断缓存中是否存在,不存在new一个返回。...而我们 上边进行 = 和 == 过程其实就是 java编译器把原始行自动转换为封装类型过程称之为**自动装箱**,相当于调用了上边所说valueOf()方法。...所以如果进行比较的话最好使用equals方法来比较 在阿里开发手册中也有说到: ?

    1K20

    opencl:cl::make_kernel进化

    所有变长参数类型进行识别, * 对于memory_cl类型参数,根据需要在kernel执行前上传数据到设备, * 并在kernel执行后根据需要下载输出数据到主机 * 模板N参数,用于调试知道哪个参数出错...>::type k(kernel); 这里make_make_kernel也是一个模板函数,用来实例化cl::make_kernel为什么要这么做呢?...make_make_kernel模板函数就是实现这个功能,下面是make_make_kernel代码实现 /* 模板函数返回make_kernel执行里需要 * 对于普通,就是本身 *...* 根据模板参数,创建cl::make_kernel * 创建cl::make_kernel所有的模板参数都会调用 kernel_type模板函数, * 以获取实例化cl::make_kernel...神奇memory_cl 前面一直不断被提起用来封装OpenCL内存对象memory_cl是个什么神奇东东?呵呵,其实并不复杂,就是抽象而已,下面是这个主要实现代码和函数声明

    1.4K20

    Chapter 5: Rvalue References, Move Semantics, PF

    ,而且std::forward完全可以使用static_cast来代替 但是使用std::forward来代替std::move需要额外接收一个模板类型参数,且该模板参数不能是引用类型,因为编码方式决定了传递值必须是一个右值...使用static_cast来代替std::forward需要在每个需要地方手动编写转换过程,这种方式不够简洁且会出错。...这样它就会产生许许多多参数类型重载实例函数。 在编译器为自动生成移动和拷贝构造函数,也不能使用重载过通用引用参数构造函数,因为通用引用参数构造函数在匹配顺序上会在其他重载函数之前。...另一种高级做法,限制(constraining)采用通用应用模板 为了在特定条件下,让函数调用发生在应该发生位置上,我们需要根据条件来启用/禁用模板匹配,方式是std::enable_if,如果内部判断条件为...同样,在将MinVals传递到模板函数fwd中,这个模板参数是一个引用,它本质上和指针是一样,只不过是一个会自动解引用指针,那么在编译该函数需要对MinVals进行取地址,而MinVals此时并没有定义

    5.1K40

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

    磁盘上叫page,缓存池中叫frame 使用ExtendebleHashTable将page_id映射到frame_id 使用LRUKReplacer跟踪页面对象何时被访问,以便在必须释放一个帧以腾出空间从磁盘复制新物理页面...& constexpr if enable_if 以下内容来源于ChatGPT C++enable_if是一个模板元编程工具,用于在编译根据条件来选择是否启用或禁用特定函数模板。...它可以与函数模板模板模板别名一起使用enable_if通过在函数模板返回类型中使用模板参数作为条件来工作。...当条件为true,返回类型有效并启用函数模板; 当条件为falseenable_if会导致编译器选择其他重载或者删除该函数模板。...使用场景: constexpr if 适用于需要在编译进行条件分支情况,例如根据类型或常量表达式值执行不同代码路径。

    29330

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

    1 基本type_traits C++ 11之前通过const或者enum枚举定义一个编译期常量类型,在C++11中,则不需要这么定义,只需要从std::integral_constant进行派生即可...使用方法也很简单,派生integral_constant后,则不用再新增定义类型和枚举变量。...std::result_of可以在编译器获取可调对象返回类型,帮助解决编码过程中如下问题: 函数入参为模板参数,不能直接确定函数返回类型; 通过decltype推导函数返回类型可读性差问题; 使用后置推导类型...int main() { Fun(1); return 0; } 程序运行为最终会匹配到第二个模板函数,但是在实际匹配过程中,当匹配到void Fun(T*)用整数对T*进行替换是错误...因此,它可以在编译期间检查模板参数是否有效。使用std::enable_if可以实现一个强大重载机制,充分利用可以减少或者消除圈复杂度。如:根据不同数据基本类型转换为string进行输出。

    1.7K10

    实际工程中 C++ 模板

    我们知道,C++ 模板有个规则是 SFINAE,这不是一个单词,而是 Substitution Failure Is Not An Error 缩写,也就是说,编译器在基于模板生成代码,如果将模板类型参数置换为给定类型...>::type; 这里使用 void_t 将多个类型声明忽略掉以适应 template 中第二个类型参数: decltype(std::begin...void_t,总体思路是类似的,也是基于类型声明来让编译器选择我们想要模板实现,这里可能和上一个例子不太一样有两点。...> 里有很多 is_ 开头模板就是基于这两个,如果一个类型符合它约束,它就是 true_type 否则就是 false_type。...——奇异递归模板模式,这个模式里派生被作为基模板参数,这个声明看着有点吓人,但是它实现效果是很妙: using Number = StrongAlias<uint8_t, struct NumberTag

    2.1K20

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

    当有项目中有多个地方需要在主机端进行向量数据运算,就会比较痛苦。...如果能像模板内核代码一样,为向量运算符提供简单向量运算功能,就可以大大简化这些代码。 利用C++模板计算函数,可以实现上面的功能。...(实现其他运算符和函数也是差不多代码,因为我暂时不需要就没有继续写下去)。...代码开始有两个很长模板函数cl_vector_type和is_cl_vector,所有的其他函数模板都要用到这两个模板函数: cl_vector_type用于构造一个指定元素类型和长度opencl...有了这些模板函数支持,主机端opencl向量运算就变得像在内核代码中一样简单,还以前面的例子用模板函数重写,就是这样: cl_int4 p1={4,2,0,9}; cl_int4 p2={3,9,-

    1.7K10

    性能优化利器之constexpr

    从概念上理解的话,constexpr即常量表达式,重点在表达式字段,用于指定变量或函数可以在常量表达式中使用,可以(或者说一定)在编译求值表达式,而const则为了约束变量访问控制,表示运行时不可以直接被修改...通过本示例,可以看出,将函数声明为constexpr可以提示效率,让编译器来决定是在编译阶段还是运行阶段来进行求值,当然了,如果想了解在编译阶段求值各种细节规则,请参考constexpr in cppreference...if语句 如果您目前使用C++11进行编码,那么需要仔细阅读本节,这样可以为将来版本升级打好基础;如果您正在使用C++17进行编码,那么更得阅读本节,相信读完本节后,会有一个不一样认识。...在上述代码中,为了编译成功,我们引入了两个Square()模板函数借助std::enable_if来实现,代码上多少有点冗余,在这个时候,本节主角if constexpr 出场,完整代码如下: #include...我们借助一个Square()函数模板以及更加符合编码习惯if语句就能解决上面的问题,且比使用std::enable_if方式更为优雅和符合阅读习惯,进而提高代码可阅读性。

    40910

    C++11 JNI开发中RAII应用(一)--制作基础工具

    于是我想到了我之前写RAII(参见我之前博客《C++11实现模板化(通用化)RAII机制》),我基本思路有了: 将每个java对象local reference用我之前写raii_var封装成一个...改进raii_var 首先,为方便使用,我对《C++11实现模板化(通用化)RAII机制》中提到raii_var进行了改造,增加了*和->操作符: // *操作符,返回T对象引用 T...resource地址 //这里->操作符使用了函数模板实现,用到了is_pointer和is_class两个type_trait来判断T类型, //如果T不是指针,也不是class/struct,则没有..._get(),调用_get()将raii_obj中对象转成jstring类型 /* 根据 _T类型不同选择不同函数模板 */ template<typename...,可以根据需要加入任意数目的参数 有了这个函数,就很方便可以将任意一个函数(成员函数/普通函数)返回结果封装成一个raii_var对象。

    38810

    C++ enable_shared_from_this 具体实现

    C++ 中使用 std::shared_ptr 智能指针不当有可能会造成循环引用,因为 std::shared_ptr 内部是基于引用计数来实现, 当引用计数为 0 ,就会释放内部持有的裸指针。...但是当 a 持有 b, b 也持有 a ,相当于 a 和 b 引用计数都至少为 1,因此得不到释放,RAII 此时也无能为力。这时就需要使用 weak_ptr 来打破循环引用。...这个就需要我们回过头来看 __enable_weak_this 返回值类型,也就是下面这一坨: typename enable_if< is_convertible<_OrigPtr...这个就是模板元编程特点,编译器生成模版函数和我们手写函数逻辑完全不同,我们手写函数不合法,编译器就会报错,但是如果编译器生成出来发现不合法,编译器就会不生成这个函数。..._NOEXCEPT {} 对于第一个问题,就是 enable_if作用: enable_if::type 意思是说,如果bool值为true,enable_if 返回就是第二个模版参数

    1K30
    领券