相信很多人都見過(guò)這種代碼
1 template <class T>
2 class Test
3 {
4 };
5
6 int main()
7 {
8 Test<int> t;
9 }
這是類模板和模板類的最常見的使用了,但是想想看,見過(guò)這種寫法嗎?
1 //

2
3 MyClass<
std::string()> t;
4
5
注意紅色的部分,我沒(méi)有寫錯(cuò),它的確可以編譯通過(guò)。這時(shí)候一串大大的疑問(wèn)產(chǎn)生了:怎么類的實(shí)例也可以做模板參數(shù)嗎?不是只有類型才能做模板參數(shù)么?難道。。。
我一開始看到這個(gè)的時(shí)候,也想不明白,怎么會(huì)呢?難道是幻覺?我決定測(cè)試一下,于是我寫了下面一段代碼:
1 template <class T>
2 struct return_value
3 {
4 typedef T type;
5 };
6
7 int main()
8 {
9 test<std::string()>::type t;
10 }
編譯通過(guò)了,可以知道t的類型是:std::basic_string<char,std::char_traits<char>,std::allocator<char>> (void)
很長(zhǎng)一串,寫簡(jiǎn)單點(diǎn)就是 std::string (void).
這是個(gè)什么東西呢?如果是函數(shù)指針,怎么說(shuō)也要有個(gè)*呀,可是沒(méi)有。那這是什么呢?
它是個(gè)函數(shù)類型,不是函數(shù)指針,函數(shù)指針是指向函數(shù)類型的指針,所以沒(méi)有*(感謝eXile)。
我給個(gè)例子吧,相信大家對(duì)boost::function不陌生吧,看下面的代碼:
1 std::string Test()
2 {
3 return "Hello World!";
4 }
5
6 boost::function<std::string()> func(Test);
7
8 int main()
9 {
10 std::cout<<func();
11 }
Hello World應(yīng)該很熟悉了吧,而那個(gè)紅色的模板參數(shù)呢,其實(shí)不是調(diào)用std::string的構(gòu)造函數(shù),而是傳入std::string (void)(函數(shù)類型)。這個(gè)類型呢,沒(méi)啥用,不能實(shí)例化,也不能調(diào)用(不是函數(shù)指針),它只是作為一種類型的簽名而已。主要任務(wù)是告訴boost::function這個(gè)類,它將要接受的函數(shù)是一個(gè)接受void為參數(shù),返回std::string的一個(gè)函數(shù)而已,用來(lái)做類型推導(dǎo)。
再看個(gè)例子吧,
1 std::string Test(std::string str)
2 {
3 return "Hello " + str;
4 };
5
6 boost::function<std::string (std::string)>
7 func(Test);
8
9 int main()
10 {
11 std::cout<<func("World");
12 }
當(dāng)把簽名改成
std::string (std::string)時(shí),就容易理解了。這個(gè)看似和函數(shù)聲明一樣的模板參數(shù),主要是為了讓boost::function做類型推導(dǎo)。順便加個(gè)括號(hào),看起來(lái)像函數(shù)。括號(hào)里面是參數(shù)的類型,括號(hào)外面是返回類型。
這才是以函數(shù)指針作為模板類型的代碼:
1 std::string Test(std::string str)
2 {
3 return "Hello " + str;
4 }
5
6 template <class T>
7 class Type
8 {
9 typedef T type;
10 };
11
12 int main()
13 {
14 // use function pointor as a template argument, it's OK.
15 Type<std::string (*)(std::string)>::type func = Test;
16 // use the signature as a template argument, complier will tell you it's wrong.
17 Type<std::string (std::string)>::type fun = Test;
18
19 }
最后總結(jié)一下,這種類型的模板參數(shù)只是作為簽名而存在,純粹是為了做類型推導(dǎo)。不能實(shí)例化,不是函數(shù)指針,名字叫:函數(shù)類型。
posted on 2009-05-24 20:21
尹東斐 閱讀(2348)
評(píng)論(10) 編輯 收藏 引用