第十六章 16 1 1節練習

2021-06-25 20:52:11 字數 2638 閱讀 4741

練習16.1

給出例項化的定義。

解答:例項化,就是編譯器將乙個函式模板中的型別用乙個具體型別替換的過程。

練習16.2

編寫並測試你自己版本的compare函式。

解答:這個函式模板的實現,可以參考書中的實現。

不過這裡要注意的是,當你的實現中涉及到比較運算子的時候,需要確定你使用的型別支援比較運算子。

練習16.3

對兩個sales_data物件呼叫你的compare函式,觀察編譯器在例項化過程中如何處理錯誤。

解答:這個其實就是使用沒有比較運算子的類進行比較。

#include #include class a

int num;

};templateint compare(const t& a, const t& b) else if(std::less()(b, a)) else

}int main()

這裡就沒有使用sales_data類。自行定義了乙個沒有比較操作符的類。

然後,可以看一下編譯器那邊會給出什麼提示。

我這邊用的g++4.9.1出現的錯誤資訊比較長,不過意思都差不多,就是沒有找到『<』這個比較運算子。

練習16.4

編寫行為類似標準庫find演算法的模板。函式需要兩個模板型別引數,乙個表示函式的迭代器引數,另乙個表示值的型別。使用你的函式再乙個vector和乙個list中查詢給定值。

解答:

#include #include #include #include templateiterator find(const iterator& begin, const iterator& end, const t &element)

} return end;

}int main();

std::vectorvint(std::begin(num), std::end(num));

std::listlint(std::begin(num), std::end(num));

auto iit = find(vint.cbegin(), vint.cend(), 2);

std::cout << *iit << std::endl;

auto lit = find(lint.cbegin(), lint.cend(), 3);

std::cout << *lit << std::endl;

}

練習16.5

為6.2.4節(第195頁)中的print函式編寫模板版本,它接受乙個陣列和引用,能處理任意大小、任意元素型別的陣列。

解答:

#include #include template void print(t (&arr)[num])

}int main();

std::string str = ;

print(num);

print(str);

}

練習16.6

你認為接受乙個陣列實參的標準庫函式begin和end是如何工作的?定義你自己版本的begin和end。

解答:

#include template t* begin(t (&container)[num])

template t* end(t (&container)[num])

int main();

std::cout << begin(num) <<": val is " << *begin(num) << std::endl;

std::cout << end(num) - 1 <<": val is " << *(end(num) - 1) << std::endl;

std::cout << end(num) << std::endl; //將列印最後乙個元素後面的的位址

}

練習16.7

編寫乙個constexpr模板,返回給定陣列的大小。

解答:

#include template size_t cconstexpr(t (&arr)[num])

int main();

std::cout << cconstexpr(num) << std::endl;

}

在c++11標準中constexpr已經是關鍵字了,所以不能使用其作為函式的名字,所以這裡多加了乙個c。

不過,在編譯的時候將-std=c++11這個選項去掉,使用constexpr作為函式名就沒有問題。

在vs2013中,應該也有對應c++11的選項,不過現在的環境沒有vs2013,所以這個可能要晚些時候補上了。

練習16.8

再第97頁的「關鍵概念」中,我們注意到,c++程式設計師喜歡用!=而不喜歡<。解釋這個習慣的原因。

解答:這裡就是區別c和c++的地方,c++主打物件導向程式設計,而c是面向過程程式設計。

c++中程式設計的核心逐漸向不同型別的物件進行轉移,這些物件不一定支援小於的操作,而不等於的操作更為方便使用。

同樣,使用不等於也可以減少很多不必要的實現,從而能讓泛型程式設計的**更加優美。

c的話,大多數情況下都是對內建型別進行操作,所以在小於和不等於的選擇中,肯定選擇比較好理解的那個。

當然這裡還是有歷史原因的,教課書編寫者的一些程式設計習慣,也會潛移默化的影響讀者。

第十六章 16 2 1節練習

練習16.32 在模板實參推斷過程中發生了什麼?解答 引用 在模板實參推斷過程中改變一起使用函式呼叫中的實參型別來尋找模板實參,用這些模板實參生成的函式版本與給定的函式呼叫最為匹配。練習16.33 指出在模板實參推斷過程中允許對函式實參進行的兩種型別轉換。解答 1.const轉換,可以將乙個非con...

第十六章 16 4 3節練習

練習16.58 為你的strvec類及你為16.1.2節 第591頁 練習中編寫的vec類新增emplace back函式。解答 這個參考623頁的strvec中的emplace back實現即可。練習16.59 假定s是乙個string,解釋呼叫svec.emplace back s 會發生什麼。...

第十六章 16 5節練習

練習16.62 定義你自己版本的hash,並定義乙個sales data物件的unordered multiset。將多條交易記錄儲存到容器中,並列印其內容。解答 這個參考書中的實現吧。練習16.63 定義乙個函式模板,統計乙個給定值在乙個vector中出現的次數。測試你的函式,分別傳遞給它乙個do...