S SmartDocs
시리즈: C++ cpp 164 줄 · 업데이트 2026-04-03

function_templates.cpp

C++/Part3_泛型與STL/Ch12_模板程式設計/function_templates.cpp

// function_templates.cpp
// 函式模板的各種用法示範
// 編譯:g++ -std=c++17 -Wall -o function_templates function_templates.cpp

#include <iostream>
#include <string>
#include <cstring>

// ============================================================
// 1. 基本函式模板 — 泛型 max
// ============================================================
template <typename T>
T my_max(T a, T b) {
    return (a > b) ? a : b;
}

// ============================================================
// 2. 明確特化 — 針對 const char* 使用 strcmp 比較
// ============================================================
template <>
const char* my_max<const char*>(const char* a, const char* b) {
    return (std::strcmp(a, b) > 0) ? a : b;
}

// ============================================================
// 3. 泛型 swap
// ============================================================
template <typename T>
void my_swap(T& a, T& b) {
    T temp = a;
    a = b;
    b = temp;
}

// ============================================================
// 4. 多型別參數 — 兩個不同型別相加
// ============================================================
template <typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
    return a + b;
}

// ============================================================
// 5. 非型別模板參數 — 印出固定大小陣列
// ============================================================
template <typename T, int N>
void print_array(const T (&arr)[N]) {
    std::cout << "[";
    for (int i = 0; i < N; ++i) {
        if (i > 0) std::cout << ", ";
        std::cout << arr[i];
    }
    std::cout << "]" << std::endl;
}

// ============================================================
// 6. 泛型搜尋 — 在陣列中找目標值
// ============================================================
template <typename T, int N>
int find_in_array(const T (&arr)[N], const T& target) {
    for (int i = 0; i < N; ++i) {
        if (arr[i] == target) return i;
    }
    return -1;  // 找不到回傳 -1
}

// ============================================================
// 主程式
// ============================================================
int main() {
    std::cout << "========================================" << std::endl;
    std::cout << "  函式模板(Function Templates)示範" << std::endl;
    std::cout << "========================================\n" << std::endl;

    // --- 1. 基本函式模板 ---
    std::cout << "--- 1. 泛型 my_max ---" << std::endl;

    // 型別推導:編譯器自動推斷 T
    std::cout << "my_max(3, 7)        = " << my_max(3, 7) << std::endl;
    std::cout << "my_max(3.14, 2.71)  = " << my_max(3.14, 2.71) << std::endl;
    std::cout << "my_max('a', 'z')    = " << my_max('a', 'z') << std::endl;

    // 明確指定型別
    std::cout << "my_max<double>(3, 2) = " << my_max<double>(3, 2) << std::endl;

    // 使用 const char* 特化版本
    std::cout << "my_max(\"apple\", \"banana\") = "
              << my_max("apple", "banana") << std::endl;

    std::cout << std::endl;

    // --- 2. 泛型 swap ---
    std::cout << "--- 2. 泛型 my_swap ---" << std::endl;

    int x = 10, y = 20;
    std::cout << "交換前: x = " << x << ", y = " << y << std::endl;
    my_swap(x, y);
    std::cout << "交換後: x = " << x << ", y = " << y << std::endl;

    std::string s1 = "Hello", s2 = "World";
    std::cout << "交換前: s1 = " << s1 << ", s2 = " << s2 << std::endl;
    my_swap(s1, s2);
    std::cout << "交換後: s1 = " << s1 << ", s2 = " << s2 << std::endl;

    std::cout << std::endl;

    // --- 3. 多型別參數 ---
    std::cout << "--- 3. 多型別參數 add ---" << std::endl;

    std::cout << "add(3, 2.5)    = " << add(3, 2.5) << std::endl;
    std::cout << "add(1.5, 2)    = " << add(1.5, 2) << std::endl;

    // string + const char*
    std::string greeting = "Hello, ";
    std::cout << "add(\"Hello, \", \"World\") = "
              << add(greeting, "World") << std::endl;

    std::cout << std::endl;

    // --- 4. 非型別模板參數 — 印出陣列 ---
    std::cout << "--- 4. print_array(非型別模板參數)---" << std::endl;

    int nums[] = {1, 2, 3, 4, 5};
    double vals[] = {1.1, 2.2, 3.3};
    std::string words[] = {"C++", "is", "awesome"};

    std::cout << "int 陣列:    ";
    print_array(nums);
    std::cout << "double 陣列: ";
    print_array(vals);
    std::cout << "string 陣列: ";
    print_array(words);

    std::cout << std::endl;

    // --- 5. 泛型搜尋 ---
    std::cout << "--- 5. find_in_array(泛型搜尋)---" << std::endl;

    int idx = find_in_array(nums, 3);
    std::cout << "在 nums 中搜尋 3: 索引 = " << idx << std::endl;

    idx = find_in_array(nums, 99);
    std::cout << "在 nums 中搜尋 99: 索引 = " << idx
              << " (找不到)" << std::endl;

    int word_idx = find_in_array(words, std::string("is"));
    std::cout << "在 words 中搜尋 \"is\": 索引 = " << word_idx << std::endl;

    std::cout << std::endl;

    // --- 6. 型別推導 vs 明確指定 ---
    std::cout << "--- 6. 型別推導 vs 明確指定 ---" << std::endl;

    // 以下會編譯失敗(型別不一致),需明確指定
    // my_max(3, 2.5);  // 錯誤:T 無法同時推導為 int 和 double
    std::cout << "my_max<double>(3, 2.5) = "
              << my_max<double>(3, 2.5) << std::endl;

    std::cout << "\n========================================" << std::endl;
    std::cout << "  函式模板示範結束" << std::endl;
    std::cout << "========================================" << std::endl;

    return 0;
}

관련 글