C++ 编译器能否对类似的模板类成员函数执行全局优化?
我正在创建一个新容器。其模板参数之一是其初始容量。因此,创建具有不同初始容量的实例将导致编译器为每个模板化类生成相同的代码C++ 编译器能否对类似的模板类成员函数执行全局优化?,c++,templates,optimization,compiler-construction,C++,Templates,Optimization,Compiler Construction,我正在创建一个新容器。其模板参数之一是其初始容量。因此,创建具有不同初始容量的实例将导致编译器为每个模板化类生成相同的代码 MyVector<3> firstVector; MyVector<4> secondVector; ... if (firstVector.empty() && secondVector.empty()) { ... } MyVector-firstVector; MyVector第二向量; ... if(firstVect
MyVector<3> firstVector;
MyVector<4> secondVector;
...
if (firstVector.empty() && secondVector.empty())
{
...
}
MyVector-firstVector;
MyVector第二向量;
...
if(firstVector.empty()&&secondVector.empty())
{
...
}
此代码段将导致编译器为这两个类生成empty()
。编译器可以消除这种重复吗?首先,empty()
可能非常简单,编译器可以内联它。如果是不能内联的呢?编译器可以进行任何类型的合并,但必须使不同的函数具有不同的地址:
&MyVector<3>::empty() != &MyVector<4>::empty()
&MyVector::empty()!=&MyVector::empty()
VisualC++ 10可以根据链接器设置来显示非标准行为-在某些设置中,它将检测这些功能并将它们合并,从而违反标准。我从未见过它以标准兼容的方式进行这种消除。
可能,编译器并没有消除这种情况。考虑下面的例子:template<size_t CAPACITY>
class MyVector {
...
public:
bool empty() const { static int i = CAPACITY; return ...; }
};
然后,只生成一个副本。empty()方法是否使用模板参数?如果不是,您可以将其分解为一个非模板基类,模板基类从中继承。我认为这是一个有效的优化。如果指向函数的两个指针具有相同的类型,但指向不同的函数,则它们之间的比较必须不相等。但是您的函数类型不同。(关于MSVC10的一般情况,您是对的;
/Gy/OPT:ICF
可能导致这种情况。)标准的哪一部分规定这些必须具有唯一的地址?1.8-6表示对象必须具有唯一的地址,但函数必须(它们不是对象)是什么意思?@edA qa mort-ora-y:顺便提一句,即使&MyVector::empty()!=&MyVector::empty()
,直接调用(不是通过指针)仍然可以合并。例如,&MyVector::empty()
可以是一个简单的JMP
到&MyVector::empty()
,当前的优化器可以优化此类调用链。此参数不成立。您演示了一个合并会违反标准的案例,但这并不能反驳一般情况。@MatthieuM.,其他答案中讨论了地址不相等的另一个案例,因此我避免重复。此外,我的“假设”是理论性的。我同意@MatthieuM。这个问题的简明版本是“如果一个类模板方法不依赖于模板参数,那么编译器必须发出该类模板方法的多个副本吗?”有了这句话,很清楚为什么这个参数不成立。@MSalters:事实上,这不是我的意思。如果方法是:bool empty()const{static unsigned i=0;++i;return…;}
由于局部静态,它仍然是不可折叠的。@MatthieuM:这将是一个正确的反例(不依赖于模板参数,但它有唯一的标识)。为什么初始容量是模板参数?只是想知道,没有它,标准容器似乎运行得很好,我看不出它能够实现任何优化(我认为initial意味着容器可以自由增长)。
template<size_t CAPACITY, typename T>
class MyVector : public vector<T>
{
// using vector<T>::empty;
};