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

2
3 MyClass<
std::string()> t;
4
5
注意紅色的部分,我沒有寫錯,它的確可以編譯通過。這時候一串大大的疑問產(chǎn)生了:怎么類的實例也可以做模板參數(shù)嗎?不是只有類型才能做模板參數(shù)么?難道。。。
我一開始看到這個的時候,也想不明白,怎么會呢?難道是幻覺?我決定測試一下,于是我寫了下面一段代碼:
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 }
編譯通過了,可以知道t的類型是:std::basic_string<char,std::char_traits<char>,std::allocator<char>> (void)
很長一串,寫簡單點就是 std::string (void).
這是個什么東西呢?如果是函數(shù)指針,怎么說也要有個*呀,可是沒有。那這是什么呢?
它是個函數(shù)類型,不是函數(shù)指針,函數(shù)指針是指向函數(shù)類型的指針,所以沒有*(感謝eXile)。
我給個例子吧,相信大家對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)該很熟悉了吧,而那個紅色的模板參數(shù)呢,其實不是調(diào)用std::string的構(gòu)造函數(shù),而是傳入std::string (void)(函數(shù)類型)。這個類型呢,沒啥用,不能實例化,也不能調(diào)用(不是函數(shù)指針),它只是作為一種類型的簽名而已。主要任務(wù)是告訴boost::function這個類,它將要接受的函數(shù)是一個接受void為參數(shù),返回std::string的一個函數(shù)而已,用來做類型推導(dǎo)。
再看個例子吧,
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ù)聲明一樣的模板參數(shù),主要是為了讓boost::function做類型推導(dǎo)。順便加個括號,看起來像函數(shù)。括號里面是參數(shù)的類型,括號外面是返回類型。
這才是以函數(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ù)類型。
posted on 2009-05-24 20:21
尹東斐 閱讀(2349)
評論(10) 編輯 收藏 引用