---
# System prepended metadata

title: 技術｜C++｜C++ 實作函數時的參數優化
tags: [技術]

---

# C++ 實作函數時的參數優化
## 目標
```c++=
void func(struct& obj, float w){
    sum += w * obj.val;
    // ... other statements
}

// 當 caller 大部分的情況為 `w=1.0f` 時，要怎麼提升效能? (且同時有好的 coding style)
```
## 方法一 使用 overload
```c++=
// 修正 caller 程式碼
// w != 1.0f ，使用 func(obj, w)
// w = 1.0f ，使用 func(obj)
void func(struct& obj){
    sum += obj.val;
    doFunc();
}

void func(struct& obj, float w){
    sum += w * obj.val;
    doFunc();
}

void doFunc(){
    // ... other statements
}
```
- 可讀性差，不好維護
## 方法二 使用參數 default value
```c++=
// caller 可修可不修 (func(obj, 1.0f) )
void func(struct& obj, float w = 1.0f){
    if(w == 1.0f) {    // 應該可以這樣判斷
        sum += obj.val;
    } else {
        sum += w * obj.val;
    }
    // ... other statements
}
```
- 節省了 `sum += w * obj.val` 的效能，但增加了 if else 判斷，整體效能不一定 ?
## 方法三 可變參數模板
```c++=
// 修正 caller 程式碼
// w != 1.0f ，使用 func(obj, w)
// w = 1.0f ，使用 func(obj)
template <typename T, typename ...Ts> // T:struct&, Ts:float
void func(const T& obj, Ts... rest) {
    if(sizeof...(rest)==0){
        sum += obj.val;
    }else{
        vector<float> nums = {rest...};
        for(auto w : nums) {
            sum += obj.val * w;
        }
    }
    // ... other statements
}
```
- 試了一下，有點硬兜出來
    - https://openhome.cc/Gossip/CppGossip/VariadicTemplate.html
- 即使做得到， 感覺不該用 function template ，編譯器可以幫忙產生函數，但是實際上我們很明確只需要 `void func(struct& obj)` 和 `void func(struct& obj, float w)` 兩種
    - 不需要請編譯器幫我們生成
    - 即使生成，也仍需要類似方法二的 if else 來優化
- 不如直接明確定義即可
## 
- ![](https://i.imgur.com/dMr73qg.jpg)
###### tags: `筆記`