為什麼返回值為容器的函式不能分檔案寫(.h與.cpp)
阿新 • • 發佈:2019-01-11
在自己的地形小專案中有這麼一個函式寫在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<…>處理的任何東西都意味著編譯器在當時不為它分配儲存空間,它一直處於等待狀態直到被一個模板例項告知,在編譯器和聯結器的某一處,有一機制能去掉指定模板的多重定義。所以為了容易使用,幾乎總是在標頭檔案中放置全部的模板宣告和定義。