在編寫 C++ 函數模板時,開發者常面臨一個選擇:形參應該用 const T& 還是直接用 T?這不僅關乎效能,更關乎正確性。
考慮以下打印範圍的模板函數:
template <typename Iterator>
void printl(Iterator v1, Iterator v2) // 正確:值傳遞
{
while (v1 != v2) {
cout << *v1++ << endl;
}
}
若改為 const 引用:
template <typename Iterator>
void printl(const Iterator &v1, const Iterator &v2) // 錯誤:const 引用
{
while (v1 != v2) {
cout << *v1++ << endl; // 編譯錯誤!
}
}
關鍵在於 *v1++ 這行代碼。後置遞增運算符 ++ 會修改迭代器本身(使其指向下一個元素)。當形參聲明為 const Iterator& 時,編譯器禁止對其進行任何修改操作,因此報錯。
std::string、std::vector、自定義類)且函數不修改它時。T&& 配合 std::forward 可同時支援左值與右值,實現完美轉發。對於標準庫風格的迭代器算法,值傳遞是標準做法。迭代器設計輕量、可拷貝、語義類似指針,傳值零開銷且避免 const 限制。唯有當模板可能實例化為「不可拷貝但可移動」的類型時,才需考慮引用語義。
記住:const 是契約,違約即編譯失敗。先問「函數內會改這個參數嗎?」,再決定傳遞方式。