C++ Boost EnableIf函数使用介绍
无水先生 人气:0一、说明
Boost.EnableIf
Boost.Enable If 可以禁用重载函数模板或专用类模板。禁用意味着编译器忽略相应的模板。这有助于防止出现模棱两可的情况,即编译器不知道要使用哪个重载函数模板。它还可以更轻松地定义不仅可用于特定类型而且可用于一组类型的模板。
从 C++11 开始,Boost.EnableIf 已经成为标准库的一部分。您可以在不使用 Boost 库的情况下调用本章介绍的函数;只需包含头文件 type_traits。
二、Boost.EnableIf的示例
示例 49.1。在返回值上使用 boost::enable_if 重载函数
#include <boost/utility/enable_if.hpp> #include <type_traits> #include <string> #include <iostream> template <typename T> typename boost::enable_if<std::is_same<T, int>, T>::type create() { return 1; } template <typename T> typename boost::enable_if<std::is_same<T, std::string>, T>::type create() { return "Boost"; } int main() { std::cout << create<std::string>() << '\n'; }
示例 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 <boost/utility/enable_if.hpp> #include <type_traits> #include <iostream> template <typename T> void print(typename boost::enable_if<std::is_integral<T>, T>::type i) { std::cout << "Integral: " << i << '\n'; } template <typename T> void print(typename boost::enable_if<std::is_floating_point<T>, T>::type f) { std::cout << "Floating point: " << f << '\n'; } int main() { print<short>(1); print<long>(2); print<double>(3.14); }
示例 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 <string> template <class T> void print_has_post_increment() { // TODO: Implement this function. } int main() { print_has_post_increment<int>(); print_has_post_increment<long>(); print_has_post_increment<std::string>(); }
加载全部内容