带有别名负载的外部模板声明
extern template declaration with alias payload
考虑一下。有一个 class Derived
继承自大量模板化 class Base
的一些实例化,并且 Derived
在各种源文件中有很多用途。因此,只有一个 Derived
特定的 Base
.
实例化是合理的
C++11 通过 extern template
允许这样做,但这里的问题是我只想键入 Base
的 Derived
特定实例化一次。从技术上讲这是可能的,因为 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
处的显式实例化会使编译失败,所以这让我对 extern template
声明不必出现在任何实例化之前,所以第二个问题仍然有意义。
class 模板特化的显式实例化声明不会 阻止实例化该特化。毕竟,您仍然需要能够引用结果 class 的成员,这意味着了解其布局的一切。它所做的是防止实例化其(非内联)成员函数,因此不需要为它们发出代码。
此外,显式实例化声明必须先于任何隐式实例化源才能生效。如果你只想命名该特化的模板参数一次,请在显式实例化声明 和 定义 Derived
.
之前为其引入类型别名
考虑一下。有一个 class Derived
继承自大量模板化 class Base
的一些实例化,并且 Derived
在各种源文件中有很多用途。因此,只有一个 Derived
特定的 Base
.
C++11 通过 extern template
允许这样做,但这里的问题是我只想键入 Base
的 Derived
特定实例化一次。从技术上讲这是可能的,因为 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
处的显式实例化会使编译失败,所以这让我对 extern template
声明不必出现在任何实例化之前,所以第二个问题仍然有意义。
class 模板特化的显式实例化声明不会 阻止实例化该特化。毕竟,您仍然需要能够引用结果 class 的成员,这意味着了解其布局的一切。它所做的是防止实例化其(非内联)成员函数,因此不需要为它们发出代码。
此外,显式实例化声明必须先于任何隐式实例化源才能生效。如果你只想命名该特化的模板参数一次,请在显式实例化声明 和 定义 Derived
.