模板函式與函式模板
阿新 • • 發佈:2019-02-12
1.函式指標——指標函式
函式指標的重點是指標。表示的是一個指標,它指向的是一個函式,例子:
int (*pf)();
指標函式的重點是函式。表示的是一個函式,它的返回值是指標。例子:
int* fun();
2.陣列指標——指標陣列
陣列指標的重點是指標。表示的是一個指標,它指向的是一個數組,例子:
int (*pa)[8];
指標陣列的重點是陣列。表示的是一個數組,它包含的元素是指標。例子;
int* ap[8];
3.類模板——模板類(class template——template class)
類模板的重點是模板。表示的是一個模板,專門用於產生類的模子。例子:
template <typename T>
class Vector
{
…
};
使用這個Vector模板就可以產生很多的class(類),Vector <int> 、Vector <char> 、Vector < Vector <int> > 、Vector <Shape*> ……。
模板類的重點是類。表示的是由一個模板生成而來的類。例子:
上面的Vector <int> 、Vector <char> 、……全是模板類。
這兩個詞很容易混淆,我看到很多文章都將其用錯,甚至一些英文文章也是這樣。將他們區分開是很重要的,你也就可以理解為什麼在定義模板的標頭檔案.h時,模板的成員函式實現也必須寫在標頭檔案.h中,而不能像普通的類(class)那樣,class的宣告(declaration)寫在.h檔案中,class的定義(definition)寫在.cpp檔案中。請參照Marshall Cline的《C++ FAQ Lite》中的[34] Container classes and templates中的[34.12] Why can 't I separate the definition of my templates class from it 's declaration and put it inside a .cpp file? URL地址是http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.12
我將幾句關鍵的段落摘錄如下,英文很好理解:
In order for the compiler to generate the code, it must see both the template definition (not just declaration) and the specific types/whatever used to "fill in " the template. For example, if you 're trying to use a Foo <int> , the compiler must see both the Foo template and the fact that you 're trying to make a specific Foo <int> .
Suppose you have a template Foo defined like this:
template <class T>
class Foo {
public:
Foo();
void someMethod(T x);
private:
T x;
};
Along with similar definitions for the member functions:
template <class T>
Foo <T> ::Foo()
{
...
}
template <class T>
void Foo <T> ::someMethod(T x)
{
...
}
Now suppose you have some code in file Bar.cpp that uses Foo <int> :
// Bar.cpp
void blah_blah_blah()
{
...
Foo <int> f;
f.someMethod(5);
...
}
Clearly somebody somewhere is going to have to use the "pattern " for the constructor definition and for the someMethod() definition and instantiate those when T is actually int. But if you had put the definition of the constructor and someMethod() into file Foo.cpp, the compiler would see the template code when it compiled Foo.cpp and it would see Foo <int> when it compiled Bar.cpp, but there would never be a time when it saw both the template code and Foo <int> . So by rule above, it could never generate the code for Foo <int> ::someMethod().
關於一個預設模板引數的例子:
template <typename T = int>
class Array
{
…
};
第一次我定義這個模板並使用它的時候,是這樣用的:
Array books;//我認為有預設模板引數,這就相當於Array <int> books
上面的用法是錯誤的,編譯不會通過,原因是Array不是一個類。正確的用法是Array <> books;
這裡Array <> 就是一個用於預設模板引數的類模板所生成的一個具體類。
4.函式模板——模板函式(function template——template function)
函式模板的重點是模板。表示的是一個模板,專門用來生產函式。例子:
template <typename T>
void fun(T a)
{
…
}
在運用的時候,可以顯式(explicitly)生產模板函式,fun <int> 、fun <double> 、fun <Shape*> ……。
也可以在使用的過程中由編譯器進行模板引數推導,幫你隱式(implicitly)生成。
fun(6);//隱式生成fun <int>
fun(8.9);//隱式生成fun <double>
fun(‘a’);// 隱式生成fun <char>
Shape* ps = new Cirlcle;
fun(ps);//隱式生成fun <Shape*>
模板函式的重點是函式。表示的是由一個模板生成而來的函式。例子:
上面顯式(explicitly)或者隱式(implicitly)生成的fun <int> 、fun <Shape*> ……都是模板函式。
關於模板本身,是一個非常龐大的主題,要把它講清楚,需要的不是一篇文章,而是一本書,幸運的是,這本書已經有了:David Vandevoorde, Nicolai M. Josuttis寫的《C++ Templates: The Complete Guide》。可惜在大陸買不到紙版,不過有一個電子版在網上流傳。
模板本身的使用是很受限制的,一般來說,它們就只是一個產生類和函式的模子。除此之外,運用的領域非常少了,所以不可能有什麼模板指標存在的,即指向模板的指標,這是因為在C++中,模板就是一個程式碼的程式碼生產工具,在最終的程式碼中,根本就沒有模板本身存在,只有模板具現出來的具體類和具體函式的程式碼存在。
但是類模板(class template)還可以作為模板的模板引數(template template parameter)使用,在Andrei Alexandrescu的《Modern C++ Design》中的基於策略的設計(Policy based Design)中大量的用到。
template < typename T, template <typename U> class Y>
class Foo
{
…
};
函式指標的重點是指標。表示的是一個指標,它指向的是一個函式,例子:
int (*pf)();
指標函式的重點是函式。表示的是一個函式,它的返回值是指標。例子:
int* fun();
2.陣列指標——指標陣列
陣列指標的重點是指標。表示的是一個指標,它指向的是一個數組,例子:
int (*pa)[8];
指標陣列的重點是陣列。表示的是一個數組,它包含的元素是指標。例子;
int* ap[8];
3.類模板——模板類(class template——template class)
類模板的重點是模板。表示的是一個模板,專門用於產生類的模子。例子:
template <typename T>
class Vector
{
…
};
使用這個Vector模板就可以產生很多的class(類),Vector <int> 、Vector <char> 、Vector < Vector <int> > 、Vector <Shape*> ……。
模板類的重點是類。表示的是由一個模板生成而來的類。例子:
上面的Vector <int> 、Vector <char> 、……全是模板類。
這兩個詞很容易混淆,我看到很多文章都將其用錯,甚至一些英文文章也是這樣。將他們區分開是很重要的,你也就可以理解為什麼在定義模板的標頭檔案.h時,模板的成員函式實現也必須寫在標頭檔案.h中,而不能像普通的類(class)那樣,class的宣告(declaration)寫在.h檔案中,class的定義(definition)寫在.cpp檔案中。請參照Marshall Cline的《C++ FAQ Lite》中的[34] Container classes and templates中的[34.12] Why can 't I separate the definition of my templates class from it 's declaration and put it inside a .cpp file? URL地址是http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.12
我將幾句關鍵的段落摘錄如下,英文很好理解:
In order for the compiler to generate the code, it must see both the template definition (not just declaration) and the specific types/whatever used to "fill in " the template. For example, if you 're trying to use a Foo <int> , the compiler must see both the Foo template and the fact that you 're trying to make a specific Foo <int> .
Suppose you have a template Foo defined like this:
template <class T>
class Foo {
public:
Foo();
void someMethod(T x);
private:
T x;
};
Along with similar definitions for the member functions:
template <class T>
Foo <T> ::Foo()
{
...
}
template <class T>
void Foo <T> ::someMethod(T x)
{
...
}
Now suppose you have some code in file Bar.cpp that uses Foo <int> :
// Bar.cpp
void blah_blah_blah()
{
...
Foo <int> f;
f.someMethod(5);
...
}
Clearly somebody somewhere is going to have to use the "pattern " for the constructor definition and for the someMethod() definition and instantiate those when T is actually int. But if you had put the definition of the constructor and someMethod() into file Foo.cpp, the compiler would see the template code when it compiled Foo.cpp and it would see Foo <int> when it compiled Bar.cpp, but there would never be a time when it saw both the template code and Foo <int> . So by rule above, it could never generate the code for Foo <int> ::someMethod().
關於一個預設模板引數的例子:
template <typename T = int>
class Array
{
…
};
第一次我定義這個模板並使用它的時候,是這樣用的:
Array books;//我認為有預設模板引數,這就相當於Array <int> books
上面的用法是錯誤的,編譯不會通過,原因是Array不是一個類。正確的用法是Array <> books;
這裡Array <> 就是一個用於預設模板引數的類模板所生成的一個具體類。
4.函式模板——模板函式(function template——template function)
函式模板的重點是模板。表示的是一個模板,專門用來生產函式。例子:
template <typename T>
void fun(T a)
{
…
}
在運用的時候,可以顯式(explicitly)生產模板函式,fun <int> 、fun <double> 、fun <Shape*> ……。
也可以在使用的過程中由編譯器進行模板引數推導,幫你隱式(implicitly)生成。
fun(6);//隱式生成fun <int>
fun(8.9);//隱式生成fun <double>
fun(‘a’);// 隱式生成fun <char>
Shape* ps = new Cirlcle;
fun(ps);//隱式生成fun <Shape*>
模板函式的重點是函式。表示的是由一個模板生成而來的函式。例子:
上面顯式(explicitly)或者隱式(implicitly)生成的fun <int> 、fun <Shape*> ……都是模板函式。
關於模板本身,是一個非常龐大的主題,要把它講清楚,需要的不是一篇文章,而是一本書,幸運的是,這本書已經有了:David Vandevoorde, Nicolai M. Josuttis寫的《C++ Templates: The Complete Guide》。可惜在大陸買不到紙版,不過有一個電子版在網上流傳。
模板本身的使用是很受限制的,一般來說,它們就只是一個產生類和函式的模子。除此之外,運用的領域非常少了,所以不可能有什麼模板指標存在的,即指向模板的指標,這是因為在C++中,模板就是一個程式碼的程式碼生產工具,在最終的程式碼中,根本就沒有模板本身存在,只有模板具現出來的具體類和具體函式的程式碼存在。
但是類模板(class template)還可以作為模板的模板引數(template template parameter)使用,在Andrei Alexandrescu的《Modern C++ Design》中的基於策略的設計(Policy based Design)中大量的用到。
template < typename T, template <typename U> class Y>
class Foo
{
…
};