当前位置: 代码网 > it编程>编程语言>C/C++ > C++ using全解析

C++ using全解析

2026年04月06日 C/C++ 我要评论
一、using的三种用途c++中的using关键字有三种主要用途:用途作用示例命名空间引入引入命名空间或其中的成员using namespace std;类型别名给类型起别名using int_ptr

一、using的三种用途

c++中的 using 关键字有三种主要用途:

用途作用示例
命名空间引入引入命名空间或其中的成员using namespace std;
类型别名给类型起别名using int_ptr = int*;
模板别名给模板类型起别名template<class t> using vec = vector<t>;

二、using 命名空间引入

1. using 声明(引入单个成员)

引入命名空间中的单个成员,之后可以直接使用该成员,不用再加命名空间前缀。

#include <iostream>

int main() {
    // 没用 using 之前,必须写 std::
    std::cout << "hello" << std::endl;
    
    // 用 using 声明后,可以直接写 cout 和 endl
    using std::cout;
    using std::endl;
    
    cout << "hello" << endl;  // 不需要 std::
    
    // 其他没引入的成员,仍然需要 std::
    int a;
    std::cin >> a;  // cin 没引入,还是要写 std::
    
    return 0;
}

说明using std::cout; 的意思是“把 std 命名空间里的 cout 引入当前作用域,以后直接用 cout 就行”。只引入这一个,其他成员不受影响。

2. using 指令(引入整个命名空间)

引入整个命名空间,之后所有成员都可以直接使用。

#include <iostream>
using namespace std;  // 引入整个 std 命名空间

int main() {
    cout << "hello" << endl;  // 直接使用
    int a;
    cin >> a;
    return 0;
}

3. 使用建议

场景建议
头文件❌ 不要用 using namespace,用完全限定名(如 std::cout
源文件✅ 可以用 using namespace,但优先用 using 声明
局部作用域✅ 可以用 using namespace,不影响其他地方

4. 注意事项:避免二义性

namespace a {
    void func() { cout << "a" << endl; }
}

namespace b {
    void func() { cout << "b" << endl; }
}

using namespace a;
using namespace b;

int main() {
    func();  // ❌ 错误:不知道调用 a::func 还是 b::func
}

解决方法

方法1:不用 using,直接用完整名字

a::func();  // 明确调用 a 的 func
b::func();  // 明确调用 b 的 func

说明:最安全的方式,不会有任何歧义,推荐在头文件或大型项目中使用。

方法2:用 using 声明,只引入不冲突的成员

using a::func;  // 只引入 a 的 func
func();         // 调用 a::func
b::func();      // b 的 func 还是写全名

说明:只引入需要的成员,减少命名空间污染,同时避免冲突。

方法3:在局部作用域使用

{
    using namespace a;
    func();  // 在这个大括号里,func 指 a::func
}
{
    using namespace b;
    func();  // 在这个大括号里,func 指 b::func
}

说明:将 using namespace 限制在局部作用域,不同区域可以分别使用不同的命名空间,互不影响。

三、using 类型别名

c++11 引入了 using 作为类型别名的新语法,比传统的 typedef 更直观。

1. typedef 的用法

typedef unsigned int u_int;      // 无符号整型
typedef char* pchar;              // 字符指针
typedef int array[10];            // 数组
typedef void (*pfun)(int, int);   // 函数指针

2. using 类型别名

using u_int = unsigned int;       // 无符号整型
using pchar = char*;              // 字符指针
using array = int[10];            // 数组
using pfun = void(*)(int, int);   // 函数指针

3. 对比

类型typedefusing
基本类型typedef unsigned int u_int;using u_int = unsigned int;
指针typedef char* pchar;using pchar = char*;
数组typedef int array[10];using array = int[10];
函数指针typedef void (*pfun)(int, int);using pfun = void(*)(int, int);

using 的优势:语法更直观,尤其是函数指针,using pfun = void(*)(int, int); 比 typedef 更容易理解。

4. 更多示例

using value_type = int;
using pointer = int*;
using const_pointer = const int*;
using reference = int&;
using const_reference = const int&;

四、using 模板别名(最大优势)

using 最大的优势是支持模板别名,而 typedef 不能。

1. 定义模板别名

template<class t, size_t n>
using array = t[n];

说明array 是一个模板别名,t 是元素类型,n 是数组大小。使用时只需指定这两个参数。

2. 使用示例

int main() {
    array<int, 5> ar;      // int ar[5]
    array<int, 5> br;      // int br[5]
    
    array<double, 5> dr;   // double dr[5]
    
    array<int*, 10> par;   // int* par[10]
    
    return 0;
}

说明:一次定义,多次使用。不同大小、不同类型的数组都可以用同一个模板别名。

3. 为什么 typedef 做不到?

// typedef 做不到!必须为每个类型单独写
typedef int array_int_5[5];
typedef double array_double_5[5];
// 无法模板化

原因typedef 只能给具体的、已经确定的类型起别名。如果需要多种类型或大小的数组,只能重复写,无法模板化。

4. 实际应用场景

// 简化 stl 容器写法
template<class t>
using vec = std::vector<t>;

int main() {
    vec<int> v;        // 等价于 std::vector<int>
    vec<double> d;     // 等价于 std::vector<double>
    vec<string> s;     // 等价于 std::vector<string>
    return 0;
}

说明:每次写 std::vector<int> 太长了,用 vec<int> 代替,代码更短。而且 vec 是模板,可以生成任意类型的 vector。

五、完整示例

下面的代码演示了 using 的两种主要用法:类型别名和模板别名。

#include <iostream>
#include <vector>
using namespace std;

// 1. 类型别名:简化复杂类型
using uint = unsigned int;
using pfunc = void(*)(int);  // 函数指针类型

// 2. 模板别名:简化嵌套容器
template<class t>
using vec2d = vector<vector<t>>;  // 二维数组

void printint(int x) {
    cout << x << endl;
}

int main() {
    // 类型别名使用
    uint a = 10;           // unsigned int
    pfunc f = printint;    // 函数指针
    f(a);
    
    // 不用模板别名:写法冗长
    vector<vector<int>> m1 = {{1, 2}, {3, 4}};
    
    // 用模板别名:写法简洁
    vec2d<int> m2 = {{1, 2}, {3, 4}};  // 等价于 vector<vector<int>>
    
    for (auto& row : m2) {
        for (auto x : row) {
            cout << x << " ";
        }
        cout << endl;
    }
    
    return 0;
}

示例说明

  • 类型别名:uint 比 unsigned int 短,pfunc 让函数指针更易读
  • 模板别名:vec2d<int> 比 vector<vector<int>> 短很多,嵌套层次越深优势越明显

六、总结

用法语法作用
命名空间引入using namespace std;引入整个命名空间
using 声明using std::cout;引入单个成员
类型别名using u_int = unsigned int;给类型起别名
模板别名template<class t> using vec = vector<t>;给模板起别名

注意

  • “命名空间引入”和“using 声明”是命名空间相关的用法
  • “类型别名”和“模板别名”是类型别名相关的用法
  • 它们虽然都叫 using,但功能完全不同

到此这篇关于c++ using全解析的文章就介绍到这了,更多相关c++ using内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

  • C++中fork()函数

    C++中fork()函数

    一、fork函数核心概念fork() 是unix/linux系统下的系统调用(c++可通过<unistd.h>头文件调用),核心作用是创建一个新进程... [阅读全文]
  • C++中priority_queue的实现

    C++中priority_queue的实现

    一、priority_queue 核心定义std::priority_queue(优先队列)是 c++ stl 中的适配器容器(基于其他容器实现),本质是一个「... [阅读全文]
  • C++四个智能指针的使用小结

    C++四个智能指针的使用小结

    一、先搞懂:为什么需要智能指针?c++ 原生指针(裸指针)最大的问题是手动管理内存容易出错,比如:忘记释放内存 → 内存泄漏;提前释放内存 &rarr... [阅读全文]
  • c++中多重继承与虚继承的实现

    c++中多重继承与虚继承的实现

    一、多重继承(multiple inheritance)1. 基本概念多重继承是指一个派生类同时继承多个基类,允许派生类复用多个基类的属性和方法,是c++区别于... [阅读全文]
  • Qt中导航栏实现的详细指南

    Qt中导航栏实现的详细指南

    简介:导航栏在qt框架中是用户界面设计的关键组件,为用户提供快速访问常用功能的途径。本文详细指导如何在qt中创建和配置qtoolbar类,包括添加动作、关联槽函... [阅读全文]
  • Qt侧边栏布局的实现示例

    Qt侧边栏布局的实现示例

    一、绪论现在的很多桌面端软件或后端管理系统等都有侧边导航栏,下面介绍一下如何用qt纯代码的形式实现。二、导航栏void mainwindow::createna... [阅读全文]

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com