typedef和在C++中使用。获得更简洁代码的两种方法
目录。
- 简介
- 声明别名
- 关键区别
- 总结
简介
在这篇文章中,我们将探讨C++中的两个类型别名--typedef和using之间的区别。
- 简而言之,你把一个现有的类型,如int,重命名为Photo。
它们可以帮助你写出清晰、简明、易懂的代码。
考虑一下下面的例子,
当在一个库中工作时,创建了两个函数
int getLength();
Photo getLength();
后者似乎是更自然的选择:在声明了别名后,照片中的函数是什么就很明显了。
然而,应该重申的是,类型别名并没有真正创建一个新的类型;相反,它定义了一个同义词或调用底层类型的另一种方式。
-
像union、class等新的类型声明并不是由'typedef'引入的。相反,现有的类型被赋予新的名字,与其他标识符在同一个名字空间。
-
typedef "声明工作得很好,在大多数情况下是足够的,但它们确实有缺点,特别是在使用模板的时候很明显。在下面的章节中,我们将看看这些限制,以及'using'语句如何解决这些限制。
声明别名
在现代C++中,程序员有两个选择来声明新的类型别名。
typedef关键字是用来以典型的方式声明新的类型别名的。
typedef [original-type] [alias];
例子
typedef int Photo;
typedef std::map<std::string, std::vector<std::string>> Map;
using关键字是在C++11中引入的声明新类型别名的新方法。
using [alias] = [original-type];
例子
using Photo = int;
using Map = std::map<std::string, std::vector<std::string>>;
两种情况下的最终结果都是一样的:形成了两个别名Photo和Map,可以在任何地方使用。
关键区别
- 在C++中,using和typedef之间的一个关键区别是,'using'可以执行'typedef'可以执行的所有功能,同时允许程序员相对有效地使用模板。
别名Map有一个固定的类型:它将永远是一个std::map<std::string, std::vector< std::string >>,没有办法将它转换为其他的东西,例如变成一个std::map<int, std::vector<int>>,除非你声明一个具有该类型的新简称
。
使用C++11允许你构造一个别名模板,它是一个保持对底层类型开放的别名。你可以使用传统的类型别名,同时也可以选择事后定义模板参数。
声明一个别名模板的语法
template<[template-parameter-list]> using [alias] = [original-type];
比如说。
template<typename TA, typename TB> using Map = std::map<TA, std::vector<TB>>;
现在,不同类型的新地图变量可以被定义为如下。
// Actual type: std::map<std::string, std::vector<std::string>>
Map<std::string, std::string> mapA;
// Actual type: std::map<int, std::vector<int>>
Map<int, int> mapB;
// Actual type: std::map<int, std::vector<float>>
Map<int, float> mapC;
传统的typedef可能被用来复制这种行为,但这要困难得多。
- 从程序员的角度来看,使用 "using "语句工作是非常简单和清晰的,特别是在处理函数指针和它们的别名定义时。事实上,"using "语句提供了更多的代码可读性,如下面的例子所示。
typedef void(*func_pointer)(int);
using func_pointer = void(*)(int);
-
使用 "using "和 "typedef "语句所做的别名声明可以在代码中的任何地方进行,包括在类、命名空间和块中,但是只用 "using "语句所做的模板声明不能在类中声明。
-
在'typedef'的情况下,通用别名的声明必须始终被包裹在结构中,这与'using'语句不同,后者不需要包裹。
template<typename T>
using Account = std::unordered_map<Admission_No, std::vector<T>>;
Vs
template<typename T>
struct Account {
typedef std::map<Admission_No, std::vector<T>> type;
};
//Using the above like:
Account<AdmissionAccount>::type AdmissionDetailsAccount;
-
可以在两个不同的文件中使用typedef声明同一个变量,只要它们都指向同一类型,就不会出现错误。这在using关键字中是无效的。
-
与 "using "语句不同,"typedef "使程序员可以一次指定许多类型的别名。
typedef int x, *ptr, (*Fun)();
总结
当涉及到定义更简单的类型别名时,在typedef和using之间做出选择可能是一个个人选择的问题。typedef的主要限制是它不能与模板一起工作。using和typedef在处理非模板时的机械性能都是一样的。然而,在定义更复杂的模板别名、函数指针别名和数组引用别名时,using语句显然是个赢家。
通过OpenGenus的这篇文章,你一定对C++中的typedef与using有了完整的概念。