外部模板和类型不完整 [英] extern template & incomplete types

查看:69
本文介绍了外部模板和类型不完整的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,当我尝试优化自己的包含层次结构时,偶然发现文件 a.hpp :

Recently when I was trying to optimize my include hierarchy I stumbled upon the file a.hpp:

template<class T>
class A
{
  using t = typename T::a_t;
};

class B;

extern template class A<B>;

这似乎是错误的形式.实际上,似乎最后一个extern模板语句会导致 A< B> 的实例化,这会导致编译器抱怨类型不完整.

which seems to be ill-formed. In fact it seems as if the extern template statement at the end causes an instantiation of A<B> which causes the compiler to complain about an incomplete type.

我的目标是在 a.cpp 中定义 A< B> :

#include <b.hpp>
template class A<B>;

这样,我避免了必须包含 a.hpp 中的 b.hpp ,这似乎是减少编译时间的好主意.但是,它不起作用( a.hpp 本身无法编译!)还有更好的方法吗?

This way I avoid having to include b.hpp from a.hpp which seems like a good idea to reduce compile time. However it does not work (a.hpp on itself doesn't compile!) Is there a better way of doing this?

注意:当然,我不能只使用显式模板实例化,但这不是我想要的!如果要使用 A< B> ,我想对其进行预编译"以节省编译时间,但是如果不使用 A< B> ,则我不想包括在内每个使用 a.hpp 的文件中的 b.hpp

Note: Of course I could just not use explicit template instantiation but this is not what I want! I would like to "precompile" A<B> to save compilation time if it were used, but if A<B> is not used I don't want to include b.hpp in every file that uses a.hpp!

推荐答案

来自

用于声明a的显式实例的extern说明符类模板仅禁止定义的显式实例化以前未专用的成员函数和静态数据成员在包含声明的翻译单元中.

The extern specifier used to declare an explicit instantiation of a class template only suppresses explicit instantiations of definitions of member functions and static data members not previously specialized in the translation unit containing the declaration.

因此,如果在A中需要B的定义,则在不了解B的情况下不能使用外部模板.您当然可以尝试摆脱该要求.在给定的情况下,您可以使用t删除声明,并具有一个产生该类型的meta函数:

Thus, if a definition of B is required in A, you cannot use an extern template without knowledge of B. You could of course try to get rid of that requirement. In the given case, you could remove the using t declaration and have a meta function to yield that type:

template<typename T>
struct get_a_t;

template<typename T>
struct get_a_t<A<T>>
{
   using type = typename T::a_t;
};

不确定您的情况是否可行.一旦A需要存储 B B :: a_t ,您就需要 B .不过,引用和指针也可以.

Not sure it that is feasible in your case. As soon as A needs to store a B or a B::a_t, you need B. References and pointers would be OK, though.

这篇关于外部模板和类型不完整的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆