我正在创建一个新容器。其模板参数之一是其初始容量。因此,创建具有不同初始容量的实例将导致编译器为每个模板化类生成相同的代码。
MyVector<3> firstVector;
MyVector<4> secondVector;
...
if (firstVector.empty() && secondVector.empty())
{
...
}
此代码片段将导致编译器为这两个类生成
empty()
。编译器可以消除这种冗余吗?
首先,
empty()
可能会非常简单,编译器将能够内联它。如果无法内联怎么办?编译器可以进行任何类型的合并,但必须以不同的函数具有不同的地址的方式进行:
&MyVector<3>::empty() != &MyVector<4>::empty()
Visual C++ 10 可能会在此处表现出非标准行为,具体取决于链接器设置 - 通过某些设置,它会检测此类函数并仅合并它们,从而违反标准。我还没有见过它以符合标准的方式进行这样的消除。
编译器可能不会消除这一点。考虑以下示例:
template<size_t CAPACITY>
class MyVector {
...
public:
bool empty() const { static int i = CAPACITY; return ...; }
};
在上面的例子中,您可以看到每个
MyVector<N>::empty()
都必须是唯一的,因为 static int i
应该是该函数所独有的。即使 static int
不存在,编译器也将始终假设其可能性。因此,如果生成 empty()
的副本,则将为所有版本生成该副本。
我是从理论上回答。不知道编译器是否有一些实用的优化技术可以克服这些问题。
但是,如果您的
MyVector
看起来像这样:
template<size_t CAPACITY, typename T>
class MyVector : public vector<T>
{
// using vector<T>::empty;
};
那么,只会生成一份副本。
empty()方法是否使用模板参数? 如果没有,您可以将其分解为模板类继承的非模板化基类。