2024年4月7日 星期日

淺聊C++ 的模板(Templates)的概念

在談C++的模板(Templates)之前,需要先了解函式名稱重載(Function Overloading)。

函式名稱重載(Overloading Function Names)

什麼是函式名稱重載(Function Overloading)呢?在原文書此章節中,是以愛麗絲鏡中奇緣中的一段對話做開頭。在愛麗絲鏡中奇緣中,愛麗絲遇到矮胖子(Humpty Dumpty,英國著名兒歌中的人物)時,矮胖子提到它的領帶是白國王和白皇后送他的「非生日禮物」,對於「非生日禮物」這個詞他們有了以下對話:

「...不過這說明有三百六十四天可以得到非生日禮物。」
「當然。」愛麗絲說。
「你看,只有一天可以收到生日禮物。這對你來說多光榮呀!」
「我不明白你說的『光榮』是什麼意思。」愛麗絲說。
矮胖子輕蔑地笑了:「你當然不懂,得等我告訴你。我的意思是『你在這場辯論中徹底輸了!』」
「但是『光榮』的意思並不是『在辯論中徹底失敗』。」愛麗絲反駁地說。
「當我使用任何詞彙時,」矮胖子相當傲慢地說,「它的意思就是我想要說的意思,恰如其分,不多也不少。」
「問題是,」愛麗絲說,「你怎麼能讓一個詞,有許多不同的意思呢?」
「問題是,」矮胖子說,「哪個意思是最重要的,就這樣。」

"...— and that shows that there are three hundred and sixty-four days when you might get un-birthday presents—"
"Certainly," said Alice.
"And only one for birthday presents, you know. There's glory for you!"
"I don't know what you mean by 'glory,'" Alice said.
Humpty Dumpty smiled contemptously, "Of course you don't—till I tell you. I mean 'there's a nice knock-down argument for you!'"
"But 'glory' doesn't mean 'a nice knock-down argument,'" Alice objected.
"When I use a word," Humpty Dumpty said, in rather a scornful tone, "it means just what I choose it to mean — neither more nor less."
"The question is," said Alice, "whether you can make words mean so many different things."
"The question is," said Humpty Dumpty, "which to be master — that's all."

LEWIS CARROL, Thtough the Looking-Glass


函式名稱重載(Function Overloading)是一種程式設計概念,指的是在同一個作用域內,可以定義多個具有相同名稱但參數清單不同的函式。它們可以是參數個數不同參數類型不同或是參數的順序不同。當函式被呼叫時,C++的編譯器會根據參數型態和數量選擇符合的函式。

這個概念蠻簡單的,可以用幾個例子快速理解:

<範例1>

有兩個函式定義:

  1. double score(double time, double distance);
  2. int score(double point);

請問底下寫法會呼叫哪個score 函式?

double x = 10; 
auto final_score = score(x);

答案是函式2.


<範例2>

有兩個函式定義:

  1. void the_answer(double data1, double data2);
  2. void the_answer(double data1, int data2)

請問底下寫法會依序呼叫哪個the_answer函式? 

double y = 10;
the_answer(y, 6.0);
the_answer(5, 6); 
the_answer(5, 6.0);

答案是函式1→2→1


模板(Templates)

從剛剛的範例中應該大概能了解函式重載的概念了,其中,針對只有參數類型不同的重載函式就能導入模板(Templates)的概念。以底下的swap_value 函式為範例: 

void swap_value(int& variable1, int& variable2)
{
    int temp;
    temp = variable1;
    variable1 = variable2;
    variable2 = temp;
}

void swap_value(char& variable1, char& variable2)
{
    char temp;
    temp = variable1;
    variable1 = variable2;
    variable2 = temp;
}

因為需求,我們寫了兩個swap_value的函式,但在這兩個函式之間其實只有參數類型的不同,是否可以寫成底下這樣,並且type_of_the_variables根據需求自動替換成int或是 char

void swap_value(type_of_the_variablesvariable1type_of_the_variablesvariable2)
{
    type_of_the_variables temp;
    temp = variable1;
    variable1 = variable2;
    variable2 = temp;
}

透過模板是可以做到的,他的的寫法是由一個模板前綴(template prefix) 開始:

template <typename type_of_the_variables>
void swap_value(type_of_the_variablesvariable1type_of_the_variablesvariable2)
{
    type_of_the_variables temp;
    temp = variable1;
    variable1 = variable2;
    variable2 = temp;
}

C++編譯的過程中,會根據當時情況自動幫我們產生上面提到的void swap_value(int& variable1, int& variable2) 或是 void swap_value(char& variable1, char& variable2)等函式

所以template可以理解為讓我們寫程式變方便和簡潔的語法。

(template應用以後有時間再補)

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。