关于cpp中的template多文件限制

记得以前看到过关于cpp中的template不能将声明与实现分开的说明,但是今天看别人代码时发现又是可以的,觉得很奇怪,自己去查了一下cpp标准的说明,

Because templates are compiled when required, this forces a restriction for multi-file projects: the implementation
(definition) of a template class or function must be in the same file as its declaration. That means that we cannot
separate the interface in a separate header file, and that we must include both interface and implementation in any
file that uses the templates. 

 

这是为什么呢?

 

其实正解应该是这样的,所谓多文件其实是以编译单位来说的,而头文件根本不算是一个编译单位,它只是作为附属被include进来而已,因此这个限制是说,如果在A.cpp里实现了一个模板方法(或者类),那么如果需要在B.cpp里调用这个方法或者类,那么就会出现链接错误,因为链接器不知道跟谁链接。但是如果你只是在同一个编译单元里使用的话,那是没有任何问题的。比如你可以在A.hpp里声明一个模板函数,而在A.cpp里实现它,但是只要你不需要在别的文件(比如B.cpp)里使用这个方法,那是没有任何问题的。可是你一旦使用了这个方法,那就会报链接错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于类和对象的股票数据排序代码示例: ```cpp #include <iostream> #include <fstream> #include <algorithm> #include <vector> using namespace std; const int MAX_MEM = 32 * 1024 * 1024; // 内存最大容量 const int MAX_FILE = 100; // 最多分割成的文件数 // 股票数据类 class StockData { public: string ts_code; // 股票代码 string trade_date; // 交易日期 double open; // 开盘价 double high; // 最高价 double low; // 最低价 double close; // 收盘价 double pre_close; // 临近收盘价 double change; // 涨跌幅 double pct_chg; // 涨跌百分比 double vol; // 交易量 double amount; // 交易金额 bool operator<(const StockData &other) const { if (ts_code != other.ts_code) { return ts_code < other.ts_code; } else { return trade_date < other.trade_date; } } }; // 将内存的数据写入文件 template<class T> void outputToFile(vector<T> &data, int len, int fileNum) { string fileName = "temp" + to_string(fileNum) + ".txt"; ofstream outFile(fileName, ios::binary); for (int i = 0; i < len; i++) { outFile.write((char*)&data[i], sizeof(T)); } outFile.close(); } // 外部排序 template<class T> void externalSort(string fileName) { // 读入文件数据 ifstream inFile(fileName, ios::binary); T data; vector<T> buffer; int len = 0, fileSize = 0; inFile.read((char*)&data, sizeof(T)); while (!inFile.eof()) { fileSize += sizeof(T); buffer.push_back(data); len++; if (fileSize >= MAX_MEM) { // 内存已满,排序并写入文件 sort(buffer.begin(), buffer.end()); outputToFile(buffer, len, fileNum); len = 0; fileSize = 0; buffer.clear(); } inFile.read((char*)&data, sizeof(T)); } // 处理剩余数据 if (len > 0) { sort(buffer.begin(), buffer.end()); outputToFile(buffer, len, fileNum); } inFile.close(); // 归并排序 while (fileNum > 1) { int mergeNum = (fileNum + MAX_FILE - 1) / MAX_FILE; for (int i = 0; i < mergeNum; i++) { vector<ifstream> files; int fileStart = i * MAX_FILE; int fileEnd = min(fileStart + MAX_FILE, fileNum); for (int j = fileStart; j < fileEnd; j++) { string fileName = "temp" + to_string(j) + ".txt"; files.push_back(ifstream(fileName, ios::binary)); } // 归并排序 string outFileName = "temp" + to_string(fileNum) + ".txt"; ofstream outFile(outFileName, ios::binary); vector<T> values(files.size()); while (true) { int minIdx = -1; for (int i = 0; i < files.size(); i++) { if (files[i].read((char*)&values[i], sizeof(T))) { if (minIdx == -1 || values[i] < values[minIdx]) { minIdx = i; } } } if (minIdx == -1) { break; } else { outFile.write((char*)&values[minIdx], sizeof(T)); } } for (int i = 0; i < files.size(); i++) { files[i].close(); } outFile.close(); fileNum++; } } // 输出排序后的结果 string finalFileName = "output.txt"; ofstream finalFile(finalFileName); ifstream sortedFile("temp0.txt", ios::binary); while (sortedFile.read((char*)&data, sizeof(T))) { finalFile << data.ts_code << "," << data.trade_date << "," << data.open << "," << data.high << "," << data.low << "," << data.close << "," << data.pre_close << "," << data.change << "," << data.pct_chg << "," << data.vol << "," << data.amount << endl; } sortedFile.close(); finalFile.close(); } int main() { string fileName = "stock_data.txt"; vector<StockData> data; ifstream inFile(fileName); string line; getline(inFile, line); // 读取表头 while (getline(inFile, line)) { StockData stock; sscanf(line.c_str(), "%[^,],%[^,],%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf", stock.ts_code.c_str(), stock.trade_date.c_str(), &stock.open, &stock.high, &stock.low, &stock.close, &stock.pre_close, &stock.change, &stock.pct_chg, &stock.vol, &stock.amount); data.push_back(stock); } inFile.close(); // 进行外部排序 externalSort<StockData>(fileName); return 0; } ``` 该程序定义了一个股票数据类 `StockData`,并使用模板函数实现了外部排序功能。具体实现过程如下: 1. 定义股票数据类 `StockData`,重载 `<` 运算符以便进行排序。 2. 定义模板函数 `outputToFile`,将内存的数据写入文件。 3. 定义模板函数 `externalSort`,进行外部排序。首先读入待排序文件,将数据分块存入内存缓冲区。当内存缓冲区已满时,对缓冲区内的数据进行排序,并将排序后的数据写入文件。最后处理剩余的数据。然后将所有的小文件进行归并排序,每次归并时读取相应的文件,将数据进行排序后写入一个新的文件。最后将所有的归并结果文件合并成一个有序的文件。 4. 读入股票数据,将其存储在一个 vector ,并调用 `externalSort` 进行排序。 5. 输出排序后的结果文件。 需要注意的是,由于股票数据文件的数据类型为浮点数,因此读写文件时需要使用二进制模式。同时,为了保证排序的稳定性,需要先按照日期排序,再按照股票代码排序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值