C++编程指南32 - 模板编程时要避免过度约束以提高通用性
一:概述
由于使用模板会提高代码的抽象级别,所以在编写模板代码时,要尽量让代码更灵活、通用,而不是只针对某些特定的操作或类型。目的是为了提高代码的重用性和效率。
二:示例
举个例子,假设我们要写一个求和函数 sum。如果只要求类型 T
具备简单的“能增加”能力(比如使用 +=
或者 +
),那么我们可能会错过一些其他更通用的方式,导致只能用特定的类型(比如只能用能进行加法的类型)。这会限制代码的可扩展性和适应性。
template<typename T>
requires Incrementable<T>
T sum1(vector<T>& v, T s)
{
for (auto x : v) s += x;
return s;
}
template<typename T>
requires Simple_number<T>
T sum2(vector<T>& v, T s)
{
for (auto x : v) s = s + x;
return s;
}
这里假设 Incrementable
不支持 +
操作,Simple_number
不支持 +=
操作,我们就会过度约束 sum1
和 sum2
的调用者。而且在这种情况下,我们错失了一个编写成通用代码的机会。
改进的方式是,使用更通用的约束,比如要求类型 T
是一个“算术类型”(即支持加法和加法赋值)。这样就可以保证无论是什么类型,只要它符合“算术”的标准,就可以使用 sum
函数了。这不仅避免了对类型的过度限制,还能让代码适用于更广泛的情况。
template<typename T>
requires Arithmetic<T>
T sum(vector<T>& v, T s)
{
for (auto x : v) s += x;
return s;
}
三: 总结
-
不要过度限制模板的类型要求,让代码更通用。
-
尽量避免只要求单一操作,要考虑更通用的操作集合。
-
用概念来约束类型,而不是直接依赖操作符,这样代码能处理更多类型,增加灵活性和复用性。