如何解决带有别名负载的外部模板声明
考虑一下。有一个类 Derived
继承自重模板类 Base
的一些实例,并且 Derived
在各种源文件中有很多用途。因此,只有一个 Derived
特定的 Base
实例化是合理的。
C++11 允许通过 extern template
执行此操作,但这里的问题是我只想键入 Derived
的特定于 Base
的实例化一次。从技术上讲,这是可能的,因为 Derived
可以保存该实例化的别名,但问题是:它是否仍会强制编译器不实例化模板?
这是尝试:
// Base.hpp
template < typename Arg > struct Base { using TheArg = Arg; };
// Derived.hpp
#include "Base.hpp"
struct Derived : Base<int> { };
// The next line will be huge in real-world scenario,so I want to avoid it.
// extern template struct Base<int>;
// Instead I want this.
extern template struct Base<Derived::TheArg>;
// Derived.cpp
#include "Derived.hpp"
template struct Base<Derived::TheArg>;
// Use01.cpp
#include "Derived.hpp"
void use01() { Derived dd; }
这里的重点是强制 Use01.cpp
不实例化 Base<int>
,而是引用 Derived.cpp
处的显式实例化。
我正在使用 gcc-v9.3
进行编译,问题是:
-
extern template
声明是对翻译单元中的所有实例有效,还是仅对出现在其声明之后的 实例有效? - 使用
Derived::TheArg
而不是int
会导致延迟实例化的任何问题吗?
将 extern template
声明放在 Use01.cpp
的末尾并注释掉 Derived.cpp
处的显式实例化会使编译失败,因此这让我对 {{1} } 声明不必出现在任何实例化之前,所以第二个问题仍然有意义。
解决方法
类模板特化的显式实例化声明不会阻止实例化该特化。毕竟,您仍然需要能够引用结果类的成员,这意味着了解有关其布局的所有信息。它的作用是防止其(非内联)成员函数的实例化,因此不需要为它们发出代码。
此外,显式实例化声明必须先于任何隐式实例化源才能生效。如果您只想为该特化的模板参数命名一次,请在显式实例化声明和Derived
的定义之前为其引入类型别名。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。