是为未使用的模板类方法生成的对象代码
Is object code generated for unused template class methods?
我有一个C++模板类,它用3个不同的类型参数实例化。类只需要为其中一种类型拥有一个方法,而其他两种类型都不会调用该方法。
该方法的对象代码会生成三次(对于模板实例化的所有类型),还是只生成一次(对于实际使用它的类型)?
类模板实例化时会实例化虚拟成员函数,但非虚拟成员函数只有在调用时才会实例化。
这在C++标准的[温度指令]中有涉及(在C++11中,这是§14.7.1/10。在C++14中,它是§14.7.1/11,在C++17中它是§17.7.1/9。摘录自下面的C++17)
实现不应隐式实例化函数模板、变量模板、成员模板、非虚拟成员函数、成员类、类模板的静态数据成员,或
constexpr
if语句(9.4.1)的子语句,除非需要此类实例化
还要注意,即使某些成员函数对于给定的模板参数不可实例化,也可以实例化类模板。例如:
template <class T>
class Xyzzy
{
public:
void CallFoo() { t.foo(); } // Invoke T::foo()
void CallBar() { t.bar(); } // Invoke T::bar()
private:
T t;
};
class FooBar
{
public:
void foo() { ... }
void bar() { ... }
};
class BarOnly
{
public:
void bar() { ... }
};
int main(int argc, const char** argv)
{
Xyzzy<FooBar> foobar; // Xyzzy<FooBar> is instantiated
Xyzzy<BarOnly> baronly; // Xyzzy<BarOnly> is instantiated
foobar.CallFoo(); // Calls FooBar::foo()
foobar.CallBar(); // Calls FooBar::bar()
baronly.CallBar(); // Calls BarOnly::bar()
return 0;
}
这是有效的,即使Xyzy::CallFoo()是不可实例化的,因为没有BarOnly::foo()这样的东西。这个特性经常被用作模板元编程工具。
但是,请注意,模板的"实例化"与生成多少对象代码并不直接相关。这将取决于编译器/链接器的实现。
我认为这取决于编译器和设置。例如,我相信MSVC6生成了所有内容,但VS2005没有。规范中说编译器不应该,但在现实世界中,它取决于实际的编译器(例如,MSVC6的boost中有许多解决方案)。如果启用/opt:ref,链接器可以删除未引用的函数(对于VS,其他编译器存在等效选项)。
通常是的。
编译器真正知道的是,您的程序可以为每个类创建至少一个实例。但它不知道你会如何处理这些实例。因此,代码几乎肯定会生成。
也就是说,如果有问题的方法是而不是虚拟的,并且从未被调用,则链接器可以使用其正常的死代码删除功能来删除它们。因此,生成(和编译)的代码不会出现在最终的EXE中。
此外,这在很大程度上取决于所使用的C++编译器,因为它们并不完全相同。
- 为什么我们不在下面给出的代码中使用指针来实例化C++的实体对象?
- 如果 iostream 对象不可复制,为什么以下代码是合法的?
- 使用 gtest 框架在单元测试代码中检查目标对象的私有变量的最佳实践是什么?
- 创建跨平台 C++ 触摸管理器.在 c++ 中传递 Objective-c 对象涉及代码
- 由于缺少类模板,NVCC 编译面向对象代码时出现问题
- 使用 jni 将返回带有模板的对象的 Java 代码转换为 c++
- 在 C++ 对象包装器中安全地包含 C 代码
- 在C++代码中搜索对象的实例化位置
- 使用.natvis文件可视化VS代码中的C++对象
- C++指向对象的指针堆数组中,如何将字符串传递给特定对象?有一些代码请看一下:
- C++ 被此代码与多态性、指针和对象切片混淆
- 从本机代码返回到托管代码会损坏返回的对象
- 如果用户尝试从 JS 调用对象的未定义函数C++则回调C++代码
- 一般函数中类的概括为基类创建对象代码
- C++模板的对象代码是否在可执行文件和动态库中重复?
- 我怎么知道C++编译器是否制作线程安全的静态对象代码
- 当我尝试发射对象代码时,为什么llvm segfault在segfault
- MFC 视觉对象C++代码来检查有效的数字条目
- 理解面向对象代码的工具和方法
- 是为未使用的模板类方法生成的对象代码