C++ 模板专题 - 模板参数类型推导

一:概述

        在 C++ 中,模板形参的类型指的是在模板定义中声明的参数类型。这些形参在模板实例化时被实际类型替代。理解如何根据实参类型推导模板形参的类型至关重要。

       1. 首选解释一下左值和右值的基本概念:

  • 左值(Lvalue):表示一个可被取地址的对象,通常指向内存中的一个位置。
  • 右值(Rvalue):表示一个临时对象,不能被取地址,通常是常量、字面量或表达式的结果。

        2. 其次解释下模板形参类型有哪些?

  • T:普通类型模板参数
  • T&:左值引用模板参数
  • T&&:右值引用模板参数
  • const T:常量类型模板参数

二:模板参数类型推导规则:        

    1. 普通类型模板参数 (T)

        当使用普通类型参数时,编译器根据传入的实参类型推导出模板参数的类型。

template<typename T>
void func(T arg) {
    // ...
}

func(42);        // T 被推导为 int
func(3.14);      // T 被推导为 double
func("Hello");   // T 被推导为 const char*

  

   2. 左值引用模板参数 (T&)

    如果模板形参是左值引用(T&),则:

  • 当传入左值时,模板参数 T 被推导为左值的类型。

  • 左值引用类型保持不变。

template<typename T>
void func(T& arg) {
    // ...
}

int x = 10;
func(x);          // T 被推导为 int
   3. 右值引用模板参数 (T&&)

   右值引用模板参数的推导规则较为复杂,涉及到完美转发(Perfect Forwarding):

  • 如果传入的是左值,T 被推导为左值引用类型(T&)。

  • 如果传入的是右值,T 被推导为右值类型(不带引用)。

template<typename T>
void func(T&& arg) {
    // ...
}

int x = 10;
func(x);          // T 被推导为 int&(左值引用)

func(20);         // T 被推导为 int(右值)
4.常量类型模板参数 (const T)

如果模板形参是常量类型(const T),则:

  • 编译器根据传入的实参类型推导出 T,但参数被视为常量,不能被修改。

  • 常量推导的过程与普通类型相似。

template<typename T>
void func(const T arg) {
    // ...
}

const int a = 5;
func(a);          // T 被推导为 const int
func(10);         // T 被推导为 const int
 5. 引用折叠

        在使用 T&& 时,可能会涉及引用折叠规则。例如,当 T 被推导为左值引用时,T&& 将折叠为 T&。使用 T&& 实现完美转发时,确保在函数内部使用 std::forward<T>(arg),以保持传入参数的值类别。

template<typename T>
void wrapper(T&& arg) {
    func(std::forward<T>(arg)); // 完美转发
}

猜你喜欢

转载自blog.csdn.net/zg260/article/details/143351514