2014年3月6日 星期四

function template裡使用vector和iterator

一開始的程式碼是這樣
void Add(std::vector<double> _V)
{
for (std::vector<double>::iterator _I = _V.begin(); _I != _V.end(); ++_I)
add(*_I);
}
void Add(std::vector<CString> _V)
{
for (std::vector<CString>::iterator _I = _V.begin(); _I != _V.end(); ++_I)
add(*_I);
}
就想使用template將它們兩個合併成一組程式碼
template<class T> 
void Add(std::vector<T> _V)
{
for (std::vector<T>::iterator _I = _V.begin(); _I != _V.end(); ++_I)
add(*_I);
}
如果你也覺得這樣的程式碼沒問題,就值得繼續往下看,因為他complier一萬年也不會過!!


在Google「function template vector」之後,終於有結果了。[1]
template<typename T, typename A>
void some_func( std::vector<T,A> const& vec ) {}
但是還是不行!怎麼會這樣?!
這時,就讓我想起一句話

「M$不符合標準,因為他當自己就是標準」

所以,我就將程式碼改成這樣(測試平台: VC6)
template<class T> 
void Add(std::vector<T,std::allocator<T> > const & _V)
{
for (std::vector<T>::iterator _I = _V.begin(); _I != _V.end(); ++_I)
add(*_I);
}
就可以了!(哭哭)

但是,標準要怎麼寫呢?
我就使用MiniGW + Sublime text 2來測試一下
果然VC6的寫法不適合,那要怎麼改呢?

再Google「function template vector iterator」了一陣子,終於有結果了。[2]

改成下面這樣,就可以了!
#include <vector>
#include <iterator>
#include <string>
#include <iostream>

class Display
{
public:
template < typename T, typename A >
void Show( std::vector<T,A> const& vec )
{
typename std::vector<T>::const_iterator it;
for (it = vec.begin(); it != vec.end(); ++it)
std::cout << *it << std::endl;
}
};

int main()
{
std::vector<double> vD;
vD.push_back(2.4);
vD.push_back(2.1);
vD.push_back(2.2);
vD.push_back(2.3);

std::vector<std::string> vS;
vS.push_back("這是");
vS.push_back("這是..");
vS.push_back("這是...");
vS.push_back("這是....");
vS.push_back("...");


Display A;
A.Show(vD);

Display B;
B.Show(vS);
}
程式執行結果
2.4
2.1
2.2
2.3
這是
這是..
這是...
這是....
...

最後的最後一件事提醒,function template的定義(不是宣告唷,是定義)請寫在.h檔[3]或者使用inline

參考資料:
[1] c++ - std::vector as a template function argument - Stack Overflow
[2] c++ - Question about vector iterator in template functions - Stack Overflow
[3] fatal error LNK1120: 2 unresolved externals

沒有留言:

張貼留言