我很想知道特定情况下模板类编译的内部结构。我问这个是因为我想扩展一些现有的课程。
例如,让我们假设一个开始
template<typename T>
class LargeClass {
private:
std::unique_ptr<T> data;
// many other fields
public:
const std::unique_ptr<T>& getData() { return data; }
void setData(T* value) { data.reset(value); }
// many other methods that don't depend on T
}
这个例子让我认为,因为sizeof(std::unique_ptr<T>) == sizeof(T*)
(没有自定义删除器),所以对于任何T1和T2都是sizeof(LargeClass<T1>) == sizeof(LargeClass<T2>)
。这意味着所有offsetof(field, LargeClass<T>)
对于任何字段和T都是相同的。
那么为什么编译器会创建每个LargeClass
方法的副本,如果它们不依赖于T
?
一种不同的方法,例如
class LargeClass {
private:
T data
...
private
...
}
应强制编译器为sizeof(T)
可能更改的不同类型创建方法的多个定义,但使用带有std::aligned_storage
的{{1}}(以避免存储过大的数据)可以使这个回退到第一种情况。编译器是否足够聪明才能实现它?
总的来说,我想知道编译器是否足够智能,以避免在未使用类型变量且类结构未发生更改时(或至少在访问时不会更改的情况下)生成模板类方法的多个定义在方法中访问的字段)与否。标准是否强制执行有关它的任何内容?