防止在 C++ 中编译未使用的模板专业化
Prevent compilation of unused template specialization in c++
让我们考虑一个结构 Foo
,它由一个名为 TYPE
:
的枚举模板化
enum TYPE
{
TYPE_A,
TYPE_B
};
template<TYPE T>
struct Foo;
Foo
未定义,但仅特化了两次。一个特化将 int*
添加到 class 而另一个将指针添加到 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>
,为什么还要生成关联代码呢?
如何防止编译器为未使用的特化编译代码?有没有简单的解决方法,最好不使用预处理器宏?似乎有可能 'delete' 已经编译但未使用的代码 (cf G++ generates code for unused template specializations?)。我要的是代码连编译都不编译,这样未定义的类型MayBeNotDefined
不成问题
谢谢!
Why does the compiler need to generate code for every specializations?
编译器不需要为未使用的模板特化生成代码,但它必须确保它的定义是正确的,根据与适用于泛型的规则相同的规则 类。
How to prevent the compiler to compile code for unused specialization?
你不能。未使用的特化必须编译,但如果编译,(体面的)编译器将不会为它生成二进制代码。
但是,如果您告诉我们您的确切期望,我们可能会为您提供替代方案。例如:
enum TYPE
{
TYPE_A,
TYPE_B
};
template<TYPE T>
struct MayBeNotDefined;
// FOR PROJECT WITH MayBeNotDefined ONLY ---
template<>
struct MayBeNotDefined<TYPE_B> { typedef char type; };
// FOR PROJECT WITH MayBeNotDefined ONLY ---
template<TYPE T>
struct Foo
{
typename MayBeNotDefined<T>::type* B;
};
template<>
struct Foo<TYPE_A>
{
int* A;
};
int main()
{
Foo<TYPE_A> a;
a.A = new int;
// FOR PROJECT WITH MayBeNotDefined ONLY ---
Foo<TYPE_B> b;
b.B = new char;
// FOR PROJECT WITH MayBeNotDefined ONLY ---
}
(即使您删除了两个指定的方块也能正常工作)
让我们考虑一个结构 Foo
,它由一个名为 TYPE
:
enum TYPE
{
TYPE_A,
TYPE_B
};
template<TYPE T>
struct Foo;
Foo
未定义,但仅特化了两次。一个特化将 int*
添加到 class 而另一个将指针添加到 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>
,为什么还要生成关联代码呢?如何防止编译器为未使用的特化编译代码?有没有简单的解决方法,最好不使用预处理器宏?似乎有可能 'delete' 已经编译但未使用的代码 (cf G++ generates code for unused template specializations?)。我要的是代码连编译都不编译,这样未定义的类型
MayBeNotDefined
不成问题
谢谢!
Why does the compiler need to generate code for every specializations?
编译器不需要为未使用的模板特化生成代码,但它必须确保它的定义是正确的,根据与适用于泛型的规则相同的规则 类。
How to prevent the compiler to compile code for unused specialization?
你不能。未使用的特化必须编译,但如果编译,(体面的)编译器将不会为它生成二进制代码。
但是,如果您告诉我们您的确切期望,我们可能会为您提供替代方案。例如:
enum TYPE
{
TYPE_A,
TYPE_B
};
template<TYPE T>
struct MayBeNotDefined;
// FOR PROJECT WITH MayBeNotDefined ONLY ---
template<>
struct MayBeNotDefined<TYPE_B> { typedef char type; };
// FOR PROJECT WITH MayBeNotDefined ONLY ---
template<TYPE T>
struct Foo
{
typename MayBeNotDefined<T>::type* B;
};
template<>
struct Foo<TYPE_A>
{
int* A;
};
int main()
{
Foo<TYPE_A> a;
a.A = new int;
// FOR PROJECT WITH MayBeNotDefined ONLY ---
Foo<TYPE_B> b;
b.B = new char;
// FOR PROJECT WITH MayBeNotDefined ONLY ---
}
(即使您删除了两个指定的方块也能正常工作)