c++的using关键字有哪些用法 类型别名和成员引入【教程】

12次阅读

usingc++11后支持类型别名(如using intVec = std::vector)、模板别名(template using Ptr = std::unique_ptr)、命名空间成员引入、继承构造函数(using Base::Base)及SFINAE辅助别名。

c++的using关键字有哪些用法 类型别名和成员引入【教程】

using定义类型别名(替代typedef

在C++11及以后,using可用于声明类型别名,语法比typedef更清晰、更易读,尤其适合模板类型。

  • 基础用法:直接为已有类型起新名字,例如 using IntVec = std::vector;,之后可用 IntVec 替代冗长的 std::vector
  • 模板别名:typedef无法直接为模板特化起别名,而using支持,例如:
    template using Ptr = std::unique_ptr;
    这样就能写 PtrPtr<:string>
  • auto结合时更自然:比如 using Func = void(*)(int); 明确表达函数指针类型,比 typedef 写法更接近“变量声明”的直觉

using引入命名空间成员(using-declaration)

作用域内将某个命名空间中的特定名称“拉进来”,避免重复写作用域限定符,但比 using Namespace 更安全、更精准。

  • 在函数内部使用:例如在函数里写 using std::swap;,之后可直接调用 swap(a, b),同时仍保留 ADL(参数依赖查找)能力
  • 在类中引入基类成员:用于解决派生类隐藏基类重载函数的问题,例如:
    class Derived : public Base {
    using Base::func;
    void func(double); // 只重载了double版本,但int版本仍可通过using访问
  • 在命名空间作用域中引入:如 namespace MyLib { using std::String; },让 MyLib 内可直接用 string,不污染全局命名空间

using声明继承构造函数(C++11起)

当派生类希望复用基类的全部构造函数时,可用 using 基类名::基类名 一次性继承,无需逐个写委托构造函数。

  • 语法简洁:class Derived : public Base { using Base::Base; }; —— 所有 Base 的构造函数都会在 Derived 中可用(含默认、拷贝、移动、带参等)
  • 注意:继承的构造函数不会改变访问属性,若基类构造函数是 privateprotected,则继承后仍不可访问
  • 不继承默认/拷贝/移动赋值运算符,只继承构造函数

using配合模板和SFINAE(进阶用法)

在模板元编程中,using常与 decltypestd::declval 等组合,定义别名以简化复杂类型推导或作为SFINAE探测点。

立即学习C++免费学习笔记(深入)”;

  • 例如检测某类型是否有成员函数
    template using has_begin_t = decltype(std::declval().begin());
    后续可用 std::is_detected 或自定义 trait 判断该别名是否有效
  • 配合 std::enable_if_t 构建约束:如 template>> void foo(T);,其中 std::enable_if_t 本质就是 using enable_if_t = typename enable_if<...>::type;
  • 这类用法强调“别名即契约”:把类型计算封装成一个名字,提升可读性与复用性

text=ZqhQzanResources