C++中typedef vs using:如何选择及它们真正的区别?

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++中typedef vs using:现代开发者的完整指南



您是否曾思考过,为什么在C++代码中有些开发者写typedef,而另一些则写using?看起来两者都在做同一件事——为类型创建别名。但事实真的如此吗?如果您想编写干净、现代的代码,并避免陷入过时构造的陷阱,那么这篇文章正是为您准备的。



我们将深入探讨C++中typedef和using的区别,何时使用哪种方式,以及为什么C++社区越来越倾向于using。准备好了吗?让我们开始吧!



简史:从C到C++11



typedef源自C语言。这是声明类型别名的经典方式。它看起来像这样:



typedef unsigned long long ULL;typedef std::vector<std::string> StringVector;typedef void (*FunctionPtr)(int, double);


坦率地说,其语法并不直观。尤其是在函数指针方面——即使是经验丰富的开发者在阅读此类声明时也时常卡壳。



在C++11中,出现了一种新的构造——using(或称为别名声明)。它的语法看起来自然得多:



using ULL = unsigned long long;using StringVector = std::vector<std::string>;using FunctionPtr = void (*)(int, double);


一目了然:左边是名称,右边是类型。读起来就像“赋值”,这对任何程序员来说都直观易懂。



主要区别:模板处理



这里隐藏着typedef和using之间最重要的区别。using支持别名模板,而typedef不支持。



让我们通过一个例子来看。假设您想为带有自定义删除器的std::unique_ptr创建一个别名:



// 使用using——简单且优雅template <typename T>using CustomPtr = std::unique_ptr<T, void(*)(T*)>;

// 使用typedef——无法直接实现!// 必须通过结构体创建包装器template <typename T>struct CustomPtrOld { typedef std::unique_ptr<T, void(*)(T*)> type;};

// 使用方式:CustomPtr<int> ptr1; // using——简单CustomPtrOld<int>::type ptr2; // typedef——繁琐


感受到区别了吗?using使代码更简洁、更短。而如果您需要在模板类或函数内部使用这样的别名,区别会更加明显:



template <typename T>class Container {public:    // 使用using    using Ptr = CustomPtr<T>;        // 使用typedef——需要typename和::type    typedef typename CustomPtrOld<T>::type OldPtr;    private:    Ptr data;    OldPtr oldData;};


代码可读性:明显的赢家



即使对于简单类型,using在可读性上也更胜一筹。比较一下:



// 使用typedef——不清楚哪里是名称,哪里是类型typedef std::map<std::string, std::vector<int>> StringToIntVectorMap;

// 使用using——一切清晰明了using StringToIntVectorMap = std::map<std::string, std::vector<int>>;


当您阅读代码时,您的眼睛会自然地从左到右扫描结构。using遵循这一原则:先是名称,后是类型。而typedef则迫使您先阅读类型,再阅读名称——这违背了直觉。



函数指针:typedef的痛点



函数指针可能是许多开发者最不喜欢的C++部分。而typedef让它们更加令人困惑:



// typedef——像念咒语一样阅读typedef void (*Callback)(int, const std::string&);

// using——像普通变量一样using Callback = void (*)(int, const std

博客

书籍推荐