【BOOST C++ 15 泛型编程】(2)Boost.EnableIf
admin
2024-02-02 22:12:14

一、说明

Boost.EnableIf

        Boost.Enable If 可以禁用重载函数模板或专用类模板。禁用意味着编译器忽略相应的模板。这有助于防止出现模棱两可的情况,即编译器不知道要使用哪个重载函数模板。它还可以更轻松地定义不仅可用于特定类型而且可用于一组类型的模板。

        从 C++11 开始,Boost.EnableIf 已经成为标准库的一部分。您可以在不使用 Boost 库的情况下调用本章介绍的函数;只需包含头文件 type_traits。

二、Boost.EnableIf的示例

        示例 49.1。在返回值上使用 boost::enable_if 重载函数

#include 
#include 
#include 
#include template 
typename boost::enable_if, T>::type create()
{return 1;
}template 
typename boost::enable_if, T>::type create()
{return "Boost";
}int main()
{std::cout << create() << '\n';
}

Example 49.1

        示例 49.1 定义了函数模板 create(),它返回作为模板参数传递的类型的对象。该对象在 create() 中初始化,不接受任何参数。两个 create() 函数的签名没有区别。在这方面,create() 不是重载函数。如果 Boost.EnableIf 没有启用一个函数而禁用另一个,编译器将报告错误。

        Boost.EnableIf 提供类 boost::enable_if,这是一个需要两个参数的模板。第一个参数是条件。如果条件为真,第二个参数是 boost::enable_if 表达式的类型。诀窍在于,如果条件为假,则此类型不存在,在这种情况下,boost::enable_if 表达式是无效的 C++ 代码。然而,当涉及到模板时,编译器不会抱怨无效代码。相反,它会忽略模板并搜索另一个可能适合的模板。这个概念被称为 SFINAE,它代表“替换失败不是错误”。

        在示例 49.1 中,boost::enable_if 表达式中的两个条件都使用类 std::is_same。此类在 C++11 标准库中定义,允许您比较两种类型。因为这样的比较不是真就是假,所以使用 std::is_same 来定义条件就足够了。

        如果条件为真,相应的 create() 函数应返回作为模板参数传递给 create() 的类型的对象。这就是 T 作为第二个参数传递给 boost::enable_if 的原因。如果条件为真,则整个 boost::enable_if 表达式将替换为 T。在示例 49.1 中,编译器会看到返回 int 的函数或返回 std::string 的函数。如果使用 int 或 std::string 以外的任何其他类型调用 create(),编译器将报告错误。

        示例 49.1 显示提升。

        示例 49.2。使用 boost::enable_if 为一组类型专门化函数

#include 
#include 
#include template 
void print(typename boost::enable_if, T>::type i)
{std::cout << "Integral: " << i << '\n';
}template 
void print(typename boost::enable_if, T>::type f)
{std::cout << "Floating point: " << f << '\n';
}int main()
{print(1);print(2);print(3.14);
}

Example 49.2

        示例 49.2 使用 boost::enable_if 为一组类型特化一个函数。该函数称为 print() 并需要一个参数。它可以被重载,尽管重载要求您使用具体类型。要对一组类型(如 short、int 或 long)执行相同的操作,您可以使用 boost::enable_if 定义适当的条件。示例 49.2 使用 std::is_integral 来做到这一点。第二个 print() 函数为所有浮点数重载了 std::is_floating_point。

练习
        使 print_has_post_increment() 写入标准输出,无论类型是否支持后增量运算符。例如,对于 int 程序应该输出“int has a post increment operator”:

#include template 
void print_has_post_increment()
{// TODO: Implement this function.
}int main()
{print_has_post_increment();print_has_post_increment();print_has_post_increment();
}

相关内容

热门资讯

爱情只是个泡沫,脆弱得一触即破...   1、心痛也只是一瞬间的事,痛久了就没有知觉了  2、时间飞逝,夺走了属于我们的回忆。  3、当眼...
心累了的女生经典个性说说摘抄 ...   1、那被岁月覆盖的花开,一切白驹过隙成为空白  2、我想永远跟你在一起,却只是想想而已。  3、...
80后最爱简单而情深的空间个性...   1、只有在颠沛流离之后 ,才能重新应证时间在内心留下的痕迹  2、诺言是自己都无法相信却一定要别...
散了场的温柔,还在一遍遍温习 ...   1、谎言,经过包装有了一个更好听的名字,誓言。  2、一个人也可以过的很好,没有渴望也不会失望。...
悲伤感情观的个性说说 感情上的...   1、忘了那幼稚的誓言,现实不存在永远  2、我强颜欢笑,只是为了迩的一丝笑颜。  3、开始很美,...