防止在C ++中编译未使用的模板专业化

TL

让我们考虑一个Foo由枚举模板化的struct 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未知而发生错误

所以我有两个问题:

  • 为什么编译器需要为每个专业生成代码?我天真地认为,如果编译器遇到type变量Foo<TYPE_A>,那么它将仅生成第一个专业化的代码。如果没有Foo<TYPE_B>解析,为什么还需要生成关联的代码?

  • 如何防止编译器编译未使用的专业化代码?有没有简单的解决方法,最好不要使用预处理器宏?似乎可以“删除”已编译但未使用的代码(参见 G ++为未使用的模板专业化生成代码?)。我要的是根本不编译代码,因此未定义的类型MayBeNotDefined不是问题。

谢谢!

YSC

为什么编译器需要为每个专业生成代码?

编译器不需要为未使用的模板专业化生成代码,但是必须确保其定义正确,并遵循与应用于通用类的规则相同的规则。

如何防止编译器编译未使用的专业化代码?

你不能。未使用的专业化必须进行编译,但是如果进行编译,则(良好的)编译器将不会为其生成二进制代码。

但是,如果您告诉我们您的确切期望,我们可能会给您其他选择。例如:

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 ---
}

(即使您删除了两个指定的块,这也有效)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章