e.g。
template< class T >
class Foo
{
public:
float MethodUseOfT()
{
return m_bar.CalculateSomething();
}
float MethodNoUseOfT()
{
float blah(0.f);
...
return blah;
}
private:
T m_bar;
};
class Bar
{
public:
float CalculateSomething();
}
如果某人制作Foo<Bar>
,大多数编制者如何管理这些内容;例如,他们通常会意识到MethodNoUseOfT
没有引用模板参数并使用该信息来减少生成的机器代码的大小吗?
此外,如果MethodUseOfT
的内容很大并且只有一行引用T
,那么编译器是否会再次尝试重用为该方法的其余部分生成的机器代码?
答案 0 :(得分:0)
仅限内联;否则,由于符号被破坏,它们必须是单独的机器代码块。
答案 1 :(得分:0)
也许。
Microsoft C ++可以选择合并相同的功能(当然Foo<int>::MethodNoUseOfT()
将与Foo<double>::MethodNoUseOfT()
相同)。
通常,此选项不符合标准(因为从函数模板生成的两个常规函数需要具有不同的地址,即使它们在其他方面相同)。但是这不适用于这种情况,因为无法获取成员函数的地址(指向成员函数的指针与地址非常不同,并且比地址复杂得多) - 所以链接器也许能够做到。
如评论中所述,唯一可以确定的方法是检查编译器+链接器的输出。
简单的方法是写出类似的东西:
class FooBase
{
public:
float MethodNoUseOfT()
{
float blah(0.f);
...
return blah;
}
};
template< class T >
class Foo : public FooBase
{
public:
float MethodUseOfT()
{
return m_bar.CalculateSomething();
}
private:
T m_bar;
};
class Bar
{
public:
float CalculateSomething();
}
如果您这样做,您甚至可以将MethodNoUseOfT
的实施移动到CPP文件中。
答案 2 :(得分:0)
取决于。
重要的部分是14.7.1隐式实例化。 &#34;当在需要存在函数定义的上下文中引用特化时,隐式实例化函数模板特化。 &#34;
换句话说,&#34;优化&#34;你认为它实际上是隐式实例化的强制行为。对于显式实例化,编译器将编译所有成员(毕竟,这是显式实例化的重点)。但是,链接器仍然可以消除未使用的函数。
没有编译器会尝试重用半个模板方法。这将需要一个非常复杂的分析,这将淹没在生成代码中节省的任何时间。