1、為什麼使用traits?
考慮下面的需求,實現一個方法Advance(iter,n),接收一個迭代器iter和移動距離n,將iter向前移動n個距離。
分析,因為存在不同型別的迭代器,做同一件事情,大家的能力不一樣,做法當然不一樣。有的迭代器可以一下子移到目標,有的迭代器只能一步一步移動,進行n次。因此,在方法內,必須要判斷迭代器的型別,然後進行相應的操作。這種方法當然不好,執行期判斷型別,需要核對繼承層次中的每個類,效率差。有沒有更好的辦法呢?
2、解決辦法:
a、每個迭代器暴露一個介面,暴露自己型別的別名(使用typedef MyType Category),每個迭代器都使用相同的別名。再使用一個traits類模版,對迭代器封裝,對外暴露迭代器型別的別名,也就是內部迭代器的型別別名(使用 typedef iter::Category Category)。
b、建立多個過載方法,根據迭代器型別的真名,進行過載。
c、在Advance方法內,對iter封裝,根據型別別名,呼叫過載的方法。
3、分析編譯器編譯過程,看到Advance方法,對迭代器封裝後,暴露的Category就是iter 的Category,也就是迭代器的型別別名,在編譯時期,就可以知道迭代器的型別真名,因此,在編譯期就可以確定下來呼叫哪個過載方法。
4、其實這種場景,如果是自己的程式碼,更應該使用執行時多型(重寫)實現上面的需求。