【发布时间】:2018-05-14 13:39:30
【问题描述】:
(我很抱歉标题凌乱。我很乐意接受改进它的建议。)
我会尽量做到直截了当。我有以下代码:
file1.hpp
template <class val_t>
struct MatOps;
file2.hpp:
#include "file1.hpp"
template <> struct MatOps<float>{
static void method1(){
// Do something
}
static void method2(){
// Do something
}
static void method3(){
// Do something
}
}
文件3.hpp:
#include "file1.hpp"
template <> struct MatOps<double>{
static void method1(){
// Do something different
}
static void method2(){
// Do something different
}
static void method3(){
// Do something different
}
}
main.cpp
#include "file2.hpp"
#include "file3.hpp"
int main(){
float a,b,c,d;
MatOps<float>::method1(a,b,...);
MatOps<float>::method2(c,d,...);
return 0;
}
问题:
- 我不使用显式特化
MatOps<double>。然而,MatOps<double>真的被实例化了吗?或更粗略地说:包含 file3.hpp 是否占用任何存储空间? - 我不使用
MatOps<float>::method3(),但我正在使用类中的其他方法。由于我明确使用MatOps<float>,编译器是否为MatOps<float>::method3()生成代码?
理由:我被要求遵循 MISRA C++:2003 标准中的一些准则。虽然已经过时,但我被鼓励使用其中合理的任何东西。特别是,有一条规则如下:
头文件应用于声明对象、函数、内联函数、函数模板、typedef、宏、类和类模板,并且不应包含或生成占用的对象或函数(或函数或对象的片段)的定义存储。
头文件被认为是通过
#include指令包含的任何文件,无论名称或后缀如何。
我的代码被大量模板化,因此我可以根据此规则包含任何文件。当我进行完全专业化时,我的问题就出现了(我只做其中两个:file2.hpp 和 file3.hpp 中列出的那些)。什么是是完整的模板特化?即使不使用,是否也会为它们生成代码?最终,它们会占用存储空间吗?
【问题讨论】:
-
"是 MatOps
实际实例化的"一个对象只能在创建时实例化。如果你不做一个;它永远不会被制造出来;与不制作 MatOps<:vector>> 的方式相同 -
通常的定义是只有变量占用“存储”。代码存储在计算机中,但通常不称为存储。您能否就您的问题澄清上述内容。此外,在类(甚至是模板)中定义的任何方法都是
inline函数,因此引用中的 para1 适用。 -
@UKMonkey 由于对象没有被实例化,我可以安全地假设没有为
matOps<double>生成代码吗?那么MatOps<float>::method3()呢?我正在创建MatOps<float>,但没有使用第三种方法 -
“最终,它们会占用存储空间吗?”对于发布版本;不;链接器会将未使用的函数定义装箱。对于调试版本 - 也许。
-
在
Class template部分中,您可以在隐式实例化 下看到“...,除非在程序中使用该成员,否则它不会被实例化,并且不会不需要定义。”基本上,编译器甚至不会强制检查此类函数的定义,除非它被使用。所以,回答 2.,他们不会为MatOps<float>::method3()生成代码。
标签: c++ templates template-specialization misra explicit-specialization