目录

C-using和typedef的异同

C++ using和typedef的异同

在 C++ 中, typedefusing 都可以用来为类型创建别名,但它们有一些关键的区别和适用场景。以下是它们的异同点:


相同点

  1. 类型别名

    • 两者都可以用来为类型创建别名,简化代码。

    • 例如:

      typedef int MyInt;  // 使用 typedef
      using MyInt = int;  // 使用 using
      

      这样, MyInt 就是 int 的别名。

  2. 兼容性

    • 两者在大多数情况下可以互换使用。

不同点

特性typedefusing
语法语法较为复杂,尤其是对于复杂类型。语法更直观,类似于变量赋值。
模板别名不支持模板别名。支持模板别名。
可读性对于复杂类型,可读性较差。对于复杂类型,可读性更好。
适用范围仅适用于类型别名。适用于类型别名和模板别名。

详细说明

1. 语法
  • typedef

    • 语法较为复杂,尤其是在定义函数指针或复杂类型时,容易搞混,比如重定义函数指针

    • 例如:

      typedef void (*FuncPtr)(int, int);  // 定义函数指针类型
      
  • using

    • 语法更直观,类似于变量赋值。

    • 例如:

      using FuncPtr = void (*)(int, int);  // 定义函数指针类型
      

2. 模板别名
  • typedef

    • 不支持模板别名。

    • 例如,以下代码会报错:

      template <typename T>
      typedef std::vector<T> Vec;  // 错误!
      
    • 需要用结构体进行封装,然后才能实现和using同样的 功能

    struct myvec
    {
    	 typedef std::vector<T> val;
    };
    myvec<int>::val vec;
  • using

    • 支持模板别名。

    • 例如:

      template <typename T>
      using Vec = std::vector<T>;  // 正确!
      

3. 可读性
  • typedef

    • 对于复杂类型,可读性较差。

    • 例如:

      typedef std::map<std::string, std::vector<int>> MapType;  // 可读性较差
      
  • using

    • 对于复杂类型,可读性更好。

    • 例如:

      using MapType = std::map<std::string, std::vector<int>>;  // 可读性更好
      

4. 适用范围
  • typedef

    • 仅适用于类型别名。
  • using

    • 适用于类型别名和模板别名。

示例代码

使用 typedef
#include <iostream>
#include <vector>
#include <map>

// 定义类型别名
typedef int MyInt;
typedef std::vector<int> IntVec;
typedef std::map<std::string, int> StringToIntMap;

int main() {
    MyInt a = 10;
    IntVec vec = {1, 2, 3};
    StringToIntMap map = {{"one", 1}, {"two", 2}};

    std::cout << "a: " << a << std::endl;
    for (int v : vec) {
        std::cout << v << " ";
    }
    std::cout << std::endl;
    for (const auto& pair : map) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}
使用 using
#include <iostream>
#include <vector>
#include <map>

// 定义类型别名
using MyInt = int;
using IntVec = std::vector<int>;
using StringToIntMap = std::map<std::string, int>;

int main() {
    MyInt a = 10;
    IntVec vec = {1, 2, 3};
    StringToIntMap map = {{"one", 1}, {"two", 2}};

    std::cout << "a: " << a << std::endl;
    for (int v : vec) {
        std::cout << v << " ";
    }
    std::cout << std::endl;
    for (const auto& pair : map) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}
使用 using 定义模板别名
#include <iostream>
#include <vector>

// 定义模板别名
template <typename T>
using Vec = std::vector<T>;

int main() {
    Vec<int> vec = {1, 2, 3};
    for (int v : vec) {
        std::cout << v << " ";
    }
    std::cout << std::endl;

    return 0;
}

using还有声明命名空间的作用,typedef则没有

总结

  • typedef :适用于简单的类型别名,但在复杂场景下可读性较差,且不支持模板别名。
  • using :语法更直观,支持模板别名,推荐在现代 C++ 中使用。

在 C++11 及更高版本中,建议优先使用 using