【发布时间】:2018-05-19 04:11:22
【问题描述】:
让我们考虑一个结构 Foo,它由一个名为 TYPE 的枚举模板化:
enum TYPE
{
TYPE_A,
TYPE_B
};
template<TYPE T>
struct Foo;
Foo 没有定义,但只特化了两次。一种特化将int* 添加到类,而另一种则添加指向MayBeNotDefined 类型对象的指针:
template<>
struct Foo<TYPE_A>
{
int* A;
};
template<>
struct Foo<TYPE_B>
{
MayBeNotDefined* B;
};
我的一些项目中没有定义MayBeNotDefined类型,所以只使用了Foo<TYPE_A>:
int main()
{
Foo<TYPE_A> a;
a.A = new int;
//...
}
在其他项目中,MayBeNotDefined 实际上是在 Foo 的声明之前定义的(类似于 using MayBeNotDefined = int;)并且同时使用了 Foo<TYPE_A> 和 Foo<TYPE_B>:
int main()
{
Foo<TYPE_A> a;
Foo<TYPE_B> b;
//...
}
问题是,在第一种情况下,编译器会为两种特化生成代码,即使我只使用Foo<TYPE_A>...因此,由于MayBeNotDefined 未知,所以会发生错误。
所以我有两个问题:
为什么编译器需要为每个特化生成代码? 我天真地以为如果编译器遇到
Foo<TYPE_A>类型的变量,那么它只会生成第一个特化的代码。如果没有解析Foo<TYPE_B>,为什么还需要生成关联代码?如何防止编译器为未使用的特化编译代码? 有没有简单的解决方法,最好不使用预处理器宏?似乎可以“删除”已编译但未使用的代码 (cf G++ generates code for unused template specializations?)。我想要的是代码甚至根本没有编译,这样未定义的类型
MayBeNotDefined就不是问题了。
谢谢!
【问题讨论】:
-
模板仍然需要编译,即使它们没有被使用,就像任何其他功能一样。
if constexpr在这里为您提供了更多的灵活性,但我不认为它比#ifdef更好。 -
您需要提供minimal reproducible example。编译器认为必须生成对模板实例的引用可能是有原因的,而您忽略了这一点。其中很多是特定于编译器的,但如果没有minimal reproducible example,所有可以说的都是纯粹的猜测。
标签: c++ templates compilation conditional-compilation specialization