using支持模板别名、函数指针别名及继承访问控制,比typedef更灵活;慎用using namespace防命名冲突;配合auto可简化复杂类型推导。

using 声明类型别名:比 typedef 更灵活
用 using 定义类型别名不是语法糖,它支持模板别名,typedef 做不到。比如想给函数指针或容器模板起个简短名字,必须用 using。
-
using StrVec = std::vector<:string>;</:string>—— 等价于typedef,但更易读 -
template<typename t> using Vec = std::vector<t>;</t></typename>—— 模板别名,typedef无法实现 -
using FuncPtr = void(*)(int);—— 函数指针别名,typedef void(*FuncPtr)(int);写法更绕
注意:别名不创建新类型,只是同义词;不能用 using 给内置类型(如 int)起别名后做重载区分——编译器仍视其为原类型。
using 指令引入命名空间:小心污染作用域
using namespace std; 放在头文件里是危险操作,会导致所有包含该头文件的源文件都暴露 std 中所有名字,可能引发隐式冲突(比如你定义了 swap,又引入了 std::swap,ADL 可能调错版本)。
- 只在 .cpp 文件最底部、函数外使用
using namespace xxx;,且仅限小范围、无歧义场景 - 优先用
using std::vector;或using std::swap;这种“using 声明”,只引入需要的符号 - 在模板中慎用
using namespace,依赖查找(ADL)行为会变得不可预测
常见错误:error: reference to 'min' is ambiguous,往往就是多个 using namespace 同时拉进了不同 min 实现。
using 继承控制访问权限:替代 public/private 继承的常用写法
在派生类中用 using Base::func; 可以把基类的私有/保护成员提升为当前类的指定访问级别,这是实现“接口继承 + 实现复用”的关键手段。
-
class Derived : private Base { using Base::public_func; };—— 把基类公有函数变成派生类公有 -
using Base::operator=;—— 显式继承赋值运算符,避免编译器生成默认版本 - 若基类有重载函数(如多个
print()),using会把整组声明都带进来,不会只挑某个参数版本
陷阱:如果基类函数是 virtual,using 不会改变虚函数性质;但如果派生类自己定义了同名函数,又没加 override,可能意外屏蔽基类版本。
using 和 auto 的配合:简化复杂类型推导
auto 解决的是变量定义时的类型省略,而 using 解决的是类型命名和复用。两者常一起用,尤其在处理迭代器、lambda 类型、模板元编程结果时。
-
using It = std::vector<int>::const_iterator;</int>+for (It it = v.cbegin(); ...)比反复写长类型清爽 - lambda 类型无法显式写出,但可借
using绑定:using Filter = std::function<bool>;</bool>,再传入 lambda - 不要试图用
using T = auto;—— 语法错误,auto不能出现在using右侧
真正容易被忽略的是:当模板参数类型极深(比如 std::map<:string std::shared_ptr>>>::value_type</:string>),先用 using 拆解中间层,再用 auto 推导局部变量,比硬写或全靠 auto 更可控、更易调试。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











