面试题:C++ 中函数模板和类模板有什么区别?

在C++中,函数模板(Function Template)类模板(Class Template) 是模板编程的两个核心概念。它们的主要区别在于用途实例化方式。以下是它们的详细区别:


1. 函数模板(Function Template)

  • 定义:函数模板是一种通用的函数定义,可以用于生成不同类型的函数实例。
  • 用途:用于编写可以处理多种类型的通用函数。
  • 实例化:函数模板在调用时根据传递的参数类型自动实例化。
  • 语法
  template <typename T>
  T add(T a, T b) {
      return a + b;
  }

示例:

#include <iostream>

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    std::cout << add(1, 2) << std::endl;       // 实例化为 int add(int, int)
    std::cout << add(1.5, 2.5) << std::endl;   // 实例化为 double add(double, double)
    return 0;
}

2. 类模板(Class Template)

  • 定义:类模板是一种通用的类定义,可以用于生成不同类型的类实例。
  • 用途:用于编写可以处理多种类型的通用类。
  • 实例化:类模板在声明对象时显式指定类型参数进行实例化。
  • 语法
  template <typename T>
  class Box {
  private:
      T value;
  public:
      Box(T v) : value(v) {}
      T getValue() const { return value; }
  };

示例:

#include <iostream>

template <typename T>
class Box {
private:
    T value;
public:
    Box(T v) : value(v) {}
    T getValue() const { return value; }
};

int main() {
    Box<int> intBox(42);         // 实例化为 Box<int>
    Box<double> doubleBox(3.14); // 实例化为 Box<double>

    std::cout << intBox.getValue() << std::endl;     // 输出: 42
    std::cout << doubleBox.getValue() << std::endl;  // 输出: 3.14

    return 0;
}

3. 函数模板和类模板的区别

特性函数模板(Function Template)类模板(Class Template)
用途定义通用函数定义通用类
实例化方式根据函数调用时的参数类型自动实例化显式指定类型参数进行实例化
语法template <typename T> T func(T a, T b)template <typename T> class Box { ... }
调用方式直接调用函数声明对象时指定类型参数
类型推导支持自动类型推导不支持自动类型推导
特化支持函数模板特化支持类模板特化和部分特化
默认模板参数不支持支持

4. 函数模板的自动类型推导

函数模板支持自动类型推导,编译器可以根据传递的参数类型推导出模板参数。

示例:

template <typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    std::cout << max(1, 2) << std::endl;       // 推导为 int
    std::cout << max(1.5, 2.5) << std::endl;   // 推导为 double
    return 0;
}

5. 类模板的显式类型指定

类模板不支持自动类型推导,必须在声明对象时显式指定类型参数。

示例:

template <typename T>
class Box {
private:
    T value;
public:
    Box(T v) : value(v) {}
    T getValue() const { return value; }
};

int main() {
    Box<int> intBox(42);         // 显式指定类型为 int
    Box<double> doubleBox(3.14); // 显式指定类型为 double
    return 0;
}

6. 函数模板和类模板的特化

  • 函数模板特化:为特定类型提供特殊的实现。
  • 类模板特化:为特定类型提供特殊的类定义。

函数模板特化示例:

template <typename T>
void print(T value) {
    std::cout << "Generic: " << value << std::endl;
}

template <>
void print<int>(int value) {
    std::cout << "Specialized for int: " << value << std::endl;
}

int main() {
    print(3.14); // 调用通用版本
    print(42);   // 调用特化版本
    return 0;
}

类模板特化示例:

template <typename T>
class Box {
public:
    void print() {
        std::cout << "Generic Box" << std::endl;
    }
};

template <>
class Box<int> {
public:
    void print() {
        std::cout << "Specialized Box for int" << std::endl;
    }
};

int main() {
    Box<double> doubleBox;
    doubleBox.print(); // 输出: Generic Box

    Box<int> intBox;
    intBox.print();    // 输出: Specialized Box for int

    return 0;
}

7. 总结

  • 函数模板:用于定义通用函数,支持自动类型推导,实例化由函数调用触发。
  • 类模板:用于定义通用类,不支持自动类型推导,实例化由对象声明触发。
  • 特化:函数模板和类模板都支持特化,用于为特定类型提供特殊实现。

通过合理使用函数模板和类模板,可以编写出通用、灵活且高效的C++代码。

THE END
点赞7 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容