3 回答
TA貢獻1963條經驗 獲得超6個贊
template <class Type>
struct listNode
{
Type number;
listNode<Type> *link;
}
因為你的listNode是一個模版,只有給出具體的類型參數,編譯器才能推導出具體的代碼。
你在使用中struct listNode<int> i;那么就得到了一個保存整數類型的節點,
struct listNode<float> f; 就得到了一個保存浮點類型的節點f。如果你不給出類型,編譯器怎么知道生成什么樣子的代碼呢。
改寫一般是這樣子的
template <class _Ty>
class LinkedList
{
public:
struct listNode
{
_Ty number;
listNode<_Ty> *link;
};
typedef typename listNode<_Ty> * listNodePtr;
public:
LinkedList(){;};
void addNode(_Ty node);
......其他方法
}
用的時候
LinkedList<int> list;
LinkedList<int>::listNode node;
LinkedList<int>::listNodePtr pNode;
list.addNode(node);
TA貢獻1820條經驗 獲得超3個贊
實現模板實例化是編譯器的編譯期行為,編譯期按不同類型參數實例化模板,并且目前而言編譯器一般不會有通用且有效的優化行為(因為模板中的類型參數自由度很高,編譯器無法判斷哪個類或函數的模板實例化版本是不需要的而可以用另一些版本代替)。因此如果調用的不同類型參數數量比較多,的確會造成很明顯的代碼膨脹導致最終目標文件體積明顯增加。如果要減少目標文件體積,可以限制調用的類型參數的實例數,例如在不同的類之間盡可能使用繼承而不是直接當作相互無關的模板類型參數(不過這樣可能會略損失運行期性能,尤其是使用虛繼承時;另外面向對象范型相對于泛型而言,運行期限制更多,靈活性略差,有時候可能不得不多寫一些重復代碼)。
至于函數調用是目標代碼的運行期行為,目標代碼已經生成好了(由于是本機代碼,不會保存類型等元信息),和模板無關(模板在編譯早期展開后就可以當作不存在了)。
- 3 回答
- 0 關注
- 812 瀏覽
添加回答
舉報
