了解模板代码膨胀

时间:2016-01-07 04:24:01

标签: c++ templates

我正在阅读Scott Meyers C ++并且遇到了所谓的代码膨胀的概念。他提供了一个如何通过继承来减少它的例子:

template <typename T>
class SquareMatrixBase{
protected:
    void invert(std::size_t matrixSize);    // <------------ HERE
}

template <typename T, std::size_t n>
class SquareMatrix : private SquareMatrixBase<T>{
private:
    using SquareMatrix<T>::invert;
public:
    void invert(){ invert(n) }
}

现在,他在项目摘要中表示

  

模板生成多个类和多个函数,所以任何   不依赖于模板参数的模板代码会导致膨胀。

因此,在示例中,我们有SquareMatrixBase<T>::invert(std::size_t),它不依赖于模板参数。因此,它会导致代码膨胀。这不是我们试图消除的东西吗?我错过了什么?

2 个答案:

答案 0 :(得分:2)

  

因此,在示例中,我们有 List<Dictionary<string, object>> result = null; result = client.GetApiRequest("api/TurnoverPieChart/Get?year=" + year + "&repType=" + repType).Result; System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); StringBuilder pJsonData = new StringBuilder(); foreach (Dictionary<string, object> pData in result) { StringBuilder myJsonString = new StringBuilder(); //Dictionary<int, List<int>> MyObj = (Dictionary<int, List<int>>)pData; Dictionary<string, long[]> MyObj1 = new Dictionary<string, long[]>(); Dictionary<string, string> MyObj2 = new Dictionary<string, string>(); short count = 0; foreach (var pd in pData) { if (count == 1) { long[] arr = ((IEnumerable)pd.Value).Cast<object>() .Select(x => Convert.ToInt64(x.ToString())) .ToArray(); MyObj1.Add(pd.Key, arr); } else { MyObj2.Add(pd.Key, pd.Value.ToString()); } myJsonString.Append(count == 0 ? serializer.Serialize(MyObj2) : serializer.Serialize(MyObj1)); count++; } pJsonData.Append(myJsonString.ToString().Replace("}{", ",")); } string finalJsonData = "[" + pJsonData.ToString().Replace("}{", "},{") + "]"; return View(finalJsonData); ,它不依赖于模板参数。因此,它会导致代码膨胀。这不是我们试图消除的东西吗?我错过了什么?

没有。您错过了[{"Label":"Solapur","Data":[25836,94698,49,5149,465153,5329,6489371,11169,9369,9369,653149,645149]}]对矩阵执行的操作将取决于SquareMatrixBase<T>::invert(std::size_t),因此对每个invert进行一次T实例化是合适的。

对于invert类型和矩阵大小T的每个组合都有一个实例化 对这两个参数进行模板化 - 遵循基类的实现。它实际上只是将矩阵大小常量作为运行时值注入。

答案 1 :(得分:1)

由于SquareMatrix模板已在Tn两个参数上进行参数化,因此即使您可能具有相同的类型T,如果您有不同的类型ninvertSquareMatrix的成员函数,它会导致函数的多个版本(一个数字取决于同一{{1}的SquareMatrixT但我们实例化的大小不同。

Scott通过简单地继承仅在T上参数化的类型来证明我们如何避免这些多个副本造成的潜在膨胀,因此可以共享invert的实现,而不管值n

他将运行时的大小值传递给基类函数,因此该函数可以使用所有相同的信息。