1. 程式人生 > >為什麼返回值為容器的函式不能分檔案寫(.h與.cpp)

為什麼返回值為容器的函式不能分檔案寫(.h與.cpp)

在自己的地形小專案中有這麼一個函式寫在function.h中

#pragma once
#ifndef __FUNCTION_H__
#define __FUNCTION_H__

#include <vector>
#include <string>

using namespace std;

///string的split功能
///返回string容器,若沒有對應分隔符則返回原string
vector<string> str_split(const string str, const string pattern)
{
	//string::size_type pos = 0;
int pos = 0; vector<string> vec; string buf(str); int size = str.size(); for (int i = 0; i < size; i = pos + pattern.size())//注意這一步,原寫法是i++,在if條件最後一步為i = pos + pattern.size() - 1 { pos = buf.find(pattern, i); if (pos == -1) { string temp = buf.substr(i, size - i); vec.push_back
(temp); return vec; } else if (pos < size && pos != i) { string temp = buf.substr(i, pos - i); vec.push_back(temp); } } return vec; } #endif

本來想把函式體分開到function.cpp裡寫,但是發現會報各種不知所云的’<‘和’{‘以及缺少’;'錯誤。

因為在編譯時模板並不能生成真正的二進位制程式碼,而是在編譯呼叫模板類或函式的cpp檔案時才會去找對應的模板宣告和實現,在這種情況下編譯器是不知道實現模板類或函式的CPP檔案的存在,所以它只能找到模板類或函式的宣告而找不到實現,而只好建立一個符號寄希望於連結程式找地址。但模板類或函式的實現並不能被編譯成二進位制程式碼,結果連結程式找不到地址只好報錯了。
《C++程式設計思想》第15章(第300頁)說明了原因:
模板定義很特殊。由template<…>處理的任何東西都意味著編譯器在當時不為它分配儲存空間,它一直處於等待狀態直到被一個模板例項告知,在編譯器和聯結器的某一處,有一機制能去掉指定模板的多重定義。所以為了容易使用,幾乎總是在標頭檔案中放置全部的模板宣告和定義。