• C++
  • C++ 结构体模板(Struct Templates)完全指南

  • @ 2025-5-28 20:01:38

C++ 结构体模板(Struct Templates)完全指南

一、为什么需要结构体模板?

假设我们需要设计一个存储"键值对"的结构体:

  • 对于intstringstruct Pair { int key; string value; }
  • 对于stringdoublestruct Pair { string key; double value; }
  • 对于charboolstruct Pair { char key; bool value; }

问题:每个不同类型组合都要定义新的结构体,代码冗余。
解决方案:使用结构体模板,让结构体支持任意类型。

二、结构体模板的基本语法

// 模板定义
template <typename 类型参数>
struct 结构体名 {
    // 成员变量(使用类型参数)
    // 成员函数(可使用类型参数)
};

// 示例:通用键值对结构体
template <typename K, typename V>
struct Pair {
    K key;    // 键的类型由K决定
    V value;  // 值的类型由V决定
    
    // 构造函数
    Pair(K k, V v) : key(k), value(v) {}
    
    // 成员函数
    void print() {
        cout << "Key: " << key << ", Value: " << value << endl;
    }
};

三、结构体模板的使用示例

#include <iostream>
#include <string>
using namespace std;

// 定义通用键值对结构体模板
template <typename K, typename V>
struct Pair {
    K key;
    V value;
    
    Pair(K k, V v) : key(k), value(v) {}
    
    void print() {
        cout << "Key: " << key << ", Value: " << value << endl;
    }
};

int main() {
    // 创建int-string类型的Pair
    Pair<int, string> p1(1, "apple");
    p1.print(); // 输出:Key: 1, Value: apple
    
    // 创建string-double类型的Pair
    Pair<string, double> p2("pi", 3.14);
    p2.print(); // 输出:Key: pi, Value: 3.14
    
    // 显式指定类型
    Pair<char, bool>* p3 = new Pair<char, bool>('A', true);
    p3->print(); // 输出:Key: A, Value: 1
    delete p3;
    
    return 0;
}

四、结构体模板的特性

  1. 多类型参数:可定义多个类型参数(如template <typename K, typename V>)。
  2. 默认类型参数(C++11支持):
template <typename K, typename V = int>
struct DefaultPair {
    K key;
    V value;
};

// 使用默认类型参数
DefaultPair<string> p("age", 20); // V默认为int
  1. 成员函数模板:结构体内部的函数也可定义为模板:
template <typename T>
struct Container {
    T data;
    
    template <typename U>
    U convert() { // 将data转换为U类型
        return static_cast<U>(data);
    }
};

五、结构体模板与类模板的区别

结构体模板和类模板的唯一区别在于默认访问权限:

  • 结构体模板:默认成员为public
  • 类模板:默认成员为private
// 结构体模板(默认public)
template <typename T>
struct Point {
    T x, y;
};

// 类模板(默认private)
template <typename T>
class Circle {
    T radius;
};

六、结构体模板的实例化过程

  1. 创建对象时指定类型Pair<int, string> p;
  2. 编译器生成具体结构体
struct Pair<int, string> {
    int key;
    string value;
    // 构造函数和成员函数的具体实现
};
  1. 使用生成的结构体p.key = 1; p.value = "apple";

七、实战案例:实现通用链表节点

#include <iostream>
using namespace std;

// 链表节点结构体模板
template <typename T>
struct Node {
    T data;
    Node* next;
    
    Node(T value) : data(value), next(nullptr) {}
};

// 链表操作函数模板
template <typename T>
void printList(Node<T>* head) {
    Node<T>* current = head;
    while (current != nullptr) {
        cout << current->data << " -> ";
        current = current->next;
    }
    cout << "nullptr" << endl;
}

int main() {
    // 创建int类型链表
    Node<int>* head = new Node<int>(10);
    head->next = new Node<int>(20);
    head->next->next = new Node<int>(30);
    
    printList(head); // 输出:10 -> 20 -> 30 -> nullptr
    
    // 创建char类型链表
    Node<char>* charHead = new Node<char>('a');
    charHead->next = new Node<char>('b');
    
    printList(charHead); // 输出:a -> b -> nullptr
    
    return 0;
}

八、结构体模板的特化

当模板无法处理特定类型时,可进行特化:

// 通用模板
template <typename T>
struct Logger {
    void log(T value) {
        cout << "General: " << value << endl;
    }
};

// 特化:处理bool类型
template <>
struct Logger<bool> {
    void log(bool value) {
        cout << "Boolean: " << (value ? "true" : "false") << endl;
    }
};

// 使用
Logger<int> intLogger;
intLogger.log(42); // 输出:General: 42

Logger<bool> boolLogger;
boolLogger.log(true); // 输出:Boolean: true

九、练习题

  1. 设计结构体模板Point<T>,表示二维平面上的点,包含坐标xy,并实现计算两点距离的函数。
  2. 实现结构体模板Stack<T>,包含入栈、出栈、获取栈顶元素的功能。
  3. 创建结构体模板Result<T>,用于函数返回值,包含状态码和数据(如int状态码和T类型数据)。

十、总结

结构体模板是C++泛型编程的重要工具,它允许创建支持任意类型的结构体,提高代码复用性。通过template关键字和类型参数,编译器会在使用时自动生成对应类型的结构体实例。结构体模板广泛应用于STL(如pairvector)和各种通用数据结构中。

掌握结构体模板后,可进一步学习类模板、模板特化、可变参数模板等高级特性,构建更复杂的泛型系统。

5 条评论

  • @ 2025-5-29 21:50:53
    #include<iostream>
    using namespace std;
    
    // 结构体模板(默认public)
    template <typename T>
    struct Point {
    	int b;
    public:
    	T x, y;
    private:
    	int a;
    };
    int main() {
    	Point<int> t1;
    	t1.b=5;
    	cout<<t1.b<<endl;
    
    	return 0;
    }
    
    • @ 2025-5-29 21:45:32
      #include<iostream>
      using namespace std;
      
      template <typename T>
      struct Container {
      	T data;
      	template <typename U>
      	U convert() { // 将data转换为U类型
      		//return static_cast<U>(data);
      		//return static_cast<int>(data);
      		//return int(data);
      		return U(data);
      	}
      };
      int main() {
      	int n;
      	cin >> n;
      	
      	return 0;
      }
      
      • @ 2025-5-29 21:31:39
        #include<iostream>
        using namespace std;
        // 示例:通用键值对结构体
        template <typename K, typename V>
        struct Pair {
        	K key;    // 键的类型由K决定
        	V value;  // 值的类型由V决定
        	// 构造函数
        	Pair(K k, V v){
        		key = k;
        		value = v;
        	}
        	// 成员函数
        	void print() {
        		cout << "Key: " << key << ", Value: " << value << endl;
        	}
        };
        int main() {
        	Pair<int, string> p1={ 1, "apple"};
        	p1.print(); // 输出:Key: 1, Value: apple
        	Pair<int, string> p2(2, "bbbbb");
        	p2.print(); // 输出:Key: 1, Value: apple
        	return 0;
        }
        
        • @ 2025-5-29 21:17:56
          #include <iostream>
          #include <cstring>
          using namespace std;
          // 示例:通用键值对结构体
          template <typename K, typename V>
          struct Pair {
          	K key;    // 键的类型由K决定
          	V value;  // 值的类型由V决定
          	// 成员函数
          	void print() {
          		cout << "Key: " << key << ", Value: " << value << endl;
          	}
          };
          int main() {
          	// 创建int-string类型的Pair
          	Pair<int, string> p1 = { 1, "apple"};
          	p1.print(); // 输出:Key: 1, Value: apple
          	
          	// 创建string-double类型的Pair
          	Pair<string, double> p2 = {"pi", 3.14};
          	p2.print(); // 输出:Key: pi, Value: 3.14
          	
          	// 显式指定类型
          	//Pair<char, bool>* p3 = new Pair<char, bool>('A', true);
          	//p3->print(); // 输出:Key: A, Value: 1
          	//delete p3;
          	return 0;
          }
          
          • @ 2025-5-28 20:01:54

            🧠 C++ 结构体模板(Struct Templates)

            📚 通俗易懂讲解结构体模板,零基础也能轻松掌握!


            💡 一、什么是结构体?

            在C++中,结构体(struct) 是一种用户自定义的数据类型,可以将多个不同类型的数据组合在一起,形成一个整体。

            ✅ 示例:

            struct Student {
                string name;
                int age;
                double score;
            };
            

            📌 作用:表示一个“学生”的信息,包括姓名、年龄和分数。


            🔍 二、为什么要用结构体?

            好处 解释
            🧩 组织数据 把相关的变量组合成一个整体
            📦 逻辑清晰 更好地表达现实世界中的对象(如人、车、商品等)
            🔄 复用性强 可以创建多个结构体变量,代表不同的实例

            🛠️ 三、结构体模板是什么?

            在C++中,我们可以通过 模板(template) 创建通用的结构体,使其适用于多种数据类型。

            这就像给结构体添加了“万能适配器”,让它可以处理 intstringdouble 等各种类型。


            🧪 四、结构体模板的基本语法

            template <typename T1, typename T2>
            struct 结构体名 {
                T1 成员1;
                T2 成员2;
                // 可以有更多成员
            };
            
            • T1, T2 是类型占位符,在使用时会被具体类型替换。
            • 可以根据需要定义任意数量的类型参数。

            📌 五、结构体模板示例详解

            ✅ 示例1:定义一个通用的“键值对”结构体

            #include <iostream>
            #include <string>
            using namespace std;
            
            // 定义结构体模板
            template <typename KeyType, typename ValueType>
            struct KeyValuePair {
                KeyType key;
                ValueType value;
            
                void print() {
                    cout << "Key: " << key << ", Value: " << value << endl;
                }
            };
            

            🧪 使用方式:

            int main() {
                // 实例化为 int -> string 的键值对
                KeyValuePair<int, string> pair1;
                pair1.key = 101;
                pair1.value = "张三";
                pair1.print();  // 输出:Key: 101, Value: 张三
            
                // 实例化为 string -> double 的键值对
                KeyValuePair<string, double> pair2;
                pair2.key = "数学成绩";
                pair2.value = 95.5;
                pair2.print();  // 输出:Key: 数学成绩, Value: 95.5
            
                return 0;
            }
            

            📌 说明

            • 同一个结构体模板,通过不同类型的参数,可以构造出不同用途的结构体。
            • 函数 print() 是结构体内部定义的方法。

            🧩 六、结构体模板与函数模板结合使用

            你也可以把结构体模板和函数模板一起使用,来实现更灵活的操作。

            ✅ 示例:打印任意类型的结构体内容

            template <typename K, typename V>
            void displayPair(KeyValuePair<K, V> pair) {
                cout << "[Key]: " << pair.key << ", [Value]: " << pair.value << endl;
            }
            

            🧪 调用方式:

            KeyValuePair<string, int> pair3;
            pair3.key = "人数";
            pair3.value = 30;
            displayPair(pair3);  // 输出:[Key]: 人数, [Value]: 30
            

            🧰 七、实战练习题(附答案)

            ✅ 题目1:定义一个通用的“坐标点”结构体模板,支持二维点(x, y)

            template <typename T>
            struct Point {
                T x;
                T y;
            
                void show() {
                    cout << "Point(" << x << ", " << y << ")" << endl;
                }
            };
            
            int main() {
                Point<int> p1;
                p1.x = 10;
                p1.y = 20;
                p1.show();  // 输出:Point(10, 20)
            
                Point<double> p2;
                p2.x = 3.14;
                p2.y = 2.71;
                p2.show();  // 输出:Point(3.14, 2.71)
            
                return 0;
            }
            

            ✅ 题目2:定义一个“图书信息”结构体模板,包含书名、作者、价格(价格支持整数或浮点数)

            template <typename PriceType>
            struct Book {
                string title;
                string author;
                PriceType price;
            
                void info() {
                    cout << "书名:" << title << endl;
                    cout << "作者:" << author << endl;
                    cout << "价格:" << price << endl;
                }
            };
            
            int main() {
                Book<double> book1;
                book1.title = "C++从入门到放弃";
                book1.author = "小明";
                book1.price = 89.9;
                book1.info();
            
                return 0;
            }
            

            🧠 八、总结(结构体模板知识点一览表)

            知识点 内容
            结构体定义 使用 struct 关键字
            模板关键字 template <typename T>
            类型参数 可以是任意数量,如 T1, T2, ...
            应用场景 表示通用的数据结构,如键值对、坐标点等
            优势 支持多类型,提高代码复用性
            注意事项 成员操作需兼容传入类型(如不能对字符串做加法运算)

            🎯 九、鼓励语

            同学们,结构体模板就像是编程中的“乐高积木”,你可以用它拼出各种复杂而优雅的数据模型!只要你理解了模板的思想,就能写出强大又灵活的程序。继续加油,你正在成为真正的C++玩家!💪


            📘 下节课预告:类与对象进阶(面向对象编程OOP)
            📌 想知道如何封装数据和行为?如何设计自己的类?下一讲我们将深入讲解类与对象的核心概念!

            • 1