Skip to content

Wiki

using

About 10 min read

1.What problem does this section solve?

In C, use typedef to create type aliases. However, the syntax of typedef is very awkward, especially when creating aliases for function pointers and templates; the notation is unintuitive and hard to read.

C++11 introduced using alias declarations, with clearer syntax, and also supports template aliases (typedef could not do this).

2.What is this feature?

using There are two common uses:

  1. Type aliases : Give an existing type a new name, similar to typedef but with clearer syntax.
  2. Template aliases : Give a template type an alias (typedef cannot do this).

3.C++ Standard Edition

C++11 (type alias syntax), C++11 template alias.

4.Required header files

No additional header files are required.using is a language keyword.

5.Basic syntax

// 类型别名
using 新名字 = 已有类型;

// 模板别名
template<typename T>
using 新名字 = 模板类型<T...>;

6.Comparison with typedef

Scenario typedef using
Primitive types typedef int Integer; using Integer = int;
Function pointers typedef void (*Func)(int); using Func = void(*)(int);
Arrays typedef int Arr10[10]; using Arr10 = int[10];
Template aliases ❌ Not supported using Vec<T> = std::vector<T>;

7.What can be done with using, and what cannot be done

using creates atype aliasnot a new type. It can make complex types easier to read, but it cannot prevent you from mixing up two types with the same underlying type.

Requirement Is using suitable? Description
Shorten complex type names ✅ Suitable using Callback = std::function<void(int)>;
Unify business names within a project ✅ Suitable using UserId = int; Make code more semantic
Simplified way to define templates ✅ Very suitable template<typename T> using Vec = std::vector<T>;
Prevent different business types from being passed incorrectly to each other ❌ Not enough using Meter = double; and using Second = double; are essentially both still double
Create a truly new type Use struct / class / enum class Only then can the compiler help you check for mixing

8.Example code

8.1.Example 1: using basics—replacing typedef

#include <iostream>
#include <string>
#include <vector>

// 旧写法(typedef)
typedef std::vector<int> IntVector1;

// 新写法(using)
using IntVector2 = std::vector<int>;

int main()
{
    // 两种写法效果完全一样
    IntVector1 v1 = {1, 2, 3};
    IntVector2 v2 = {4, 5, 6};

    std::cout << "v1: ";
    for (int n : v1) std::cout << n << " ";
    std::cout << "\n";

    std::cout << "v2: ";
    for (int n : v2) std::cout << n << " ";
    std::cout << "\n";

    return 0;
}

Running result:

v1: 1 2 3 
v2: 4 5 6 

8.2.Example 2: Based on Example 1, use using to create an alias for a function pointer

#include <iostream>

// typedef 的函数指针写法(别扭)
typedef int (*FuncPtr1)(int, int);

// using 的函数指针写法(直观)
using FuncPtr2 = int (*)(int, int);

int add(int a, int b)
{
    return a + b;
}

int multiply(int a, int b)
{
    return a * b;
}

int main()
{
    FuncPtr2 op1 = add;
    FuncPtr2 op2 = multiply;

    std::cout << "add(3, 5) = " << op1(3, 5) << "\n";
    std::cout << "multiply(3, 5) = " << op2(3, 5) << "\n";

    return 0;
}

Running result:

add(3, 5) = 8
multiply(3, 5) = 15

8.3.Example 3: Building on Example 2, template aliases (which typedef cannot achieve)

#include <iostream>
#include <vector>
#include <map>
#include <string>

// 模板别名:定义一个泛型的 vector
template<typename T>
using Vec = std::vector<T>;

// 模板别名:键为 string 的 map
template<typename T>
using StringMap = std::map<std::string, T>;

int main()
{
    Vec<int> vi = {1, 2, 3};
    Vec<double> vd = {1.1, 2.2, 3.3};
    StringMap<int> scores = {{"Alice", 85}, {"Bob", 92}};

    std::cout << "Vec<int>: ";
    for (int n : vi) std::cout << n << " ";
    std::cout << "\n";

    std::cout << "Vec<double>: ";
    for (double d : vd) std::cout << d << " ";
    std::cout << "\n";

    std::cout << "StringMap<int>: ";
    for (const auto& p : scores)
        std::cout << p.first << ":" << p.second << " ";
    std::cout << "\n";

    return 0;
}

Running result:

Vec<int>: 1 2 3 
Vec<double>: 1.1 2.2 3.3 
StringMap<int>: Alice:85 Bob:92 

8.4.Example 4: Building on Example 3, a using alias is not a new type

#include <iomanip>
#include <iostream>

using Meter = double;
using Second = double;

double speed(Meter distance, Second time)
{
    return distance / time;
}

struct MeterValue
{
    double value;
};

struct SecondValue
{
    double value;
};

double safe_speed(MeterValue distance, SecondValue time)
{
    return distance.value / time.value;
}

int main()
{
    Meter distance = 100.0;
    Second time = 9.58;

    std::cout << std::fixed << std::setprecision(2);
    std::cout << "speed = " << speed(distance, time) << "\n";

    // using 只是别名,下面这行语义错了,但编译器仍然允许
    std::cout << "wrong order = " << speed(time, distance) << "\n";

    MeterValue d{100.0};
    SecondValue t{9.58};
    std::cout << "safe speed = " << safe_speed(d, t) << "\n";

    // safe_speed(t, d); // ❌ 编译错误:SecondValue 不能当 MeterValue 用

    return 0;
}

Running result:

speed = 10.44
wrong order = 0.10
safe speed = 10.44

9.Operation result

See the "run results" for each example above.

10.Key syntax explanation in the example

Example What was explained Newly introduced syntax Why it is written this way Notes
Example 1 Basic type alias using Name = Type; The syntax is more intuitive,= making it clear at a glance that "alias = original type" typedef can also do this, but using is clearer
Example 2 Function pointer alias using Func = int(*)(int,int); The name is in the middle, which is easier to read than typedef where the name is sandwiched in the middle In actual projects, it is recommended to use std::function instead of raw function pointers
Example 3 Template alias template<T> using Vec = vector<T>; typedef cannot do template aliases; this is a unique capability of using Very suitable for simplifying nested template types
Example 4 using is not a new type using Meter = double、wrapper struct Aliases improve readability, structs provide type safety When it is necessary to prevent arguments from being passed in the wrong order, do not rely only on using

11.Common Errors

Error 1: Write the = direction of the using alias backwards

using int = MyInt;  // ❌ 方向反了!应该是 using 别名 = 原类型

Correct approach:using MyInt = int;

Error 2: Unrestricted use of using in header files

// 头文件中
using namespace std;  // ❌ 污染全局/外部命名空间!

Correct approach: avoid in header files using namespace, and use it only in the .cpp implementation file or inside functions.

Error 3: Confusing using declarations with using aliases

using std::cout;       // using 声明:引入名字
using MyVec = std::vector<int>;  // using 别名:创建别名

These are two different usages: the former introduces a name into the current scope, while the latter creates a type alias.

Mistake 4: Assuming that using can provide strong type checking

using UserId = int;
using ProductId = int;

void load_user(UserId id);

ProductId pid = 10;
load_user(pid);  // 能编译,因为 UserId 和 ProductId 本质都是 int

Correct approach: If mixing must be prevented, use struct UserId { int value; }; this wrapper type, or use enum class to express a finite set.

12.Usage Recommendations

  1. Use using instead of typedef: the syntax is clearer and it also supports template aliases.
  2. Make good use of template aliases to simplify code:For example using TaskMap = std::map<int, std::function<void()>>;.
  3. Do not use using namespace in header files: avoid namespace pollution.
  4. using declarations (using std::cout ) can be used in a .cpp file or inside a function to simplify code.
  5. When strong typing is needed, do not rely only on using:using improves readability,struct/class/enum class Only then can the type itself be changed.

13.Summary

  • using NewName = OldType;More typedef intuitive than syntax.
  • template<typename T> using Alias = ...; It is a template alias that typedef cannot achieve.
  • Function pointer aliases and container type aliases are very practical in projects.
  • using It is only an alias, not a new type; when type safety is needed, a wrapper type must be introduced.
  • Do not confuse the using alias and the using declaration (namespace introduction).