考虑一个类模板S
:
[ s.hpp
]
template <typename>
struct S
{
void f() { /* ... */ }
void g() { /* ... */ }
};
这个类模板还附带了一个包含S<int>::g()
专门化的源文件:
[ s.cpp
]
template <>
void S<int>::g() { /* ... */ }
S
多次示例化为S<int>
,为了避免S<int>
的多次示例化,加快编译速度,我想在头文件s.hpp
中引入一个 * 显式示例化声明 *(extern template
),在源文件s.cpp
中引入一个对应的 * 显式示例化定义 *:
[ s.hpp
] (已修改)
template <typename>
struct S
{
void f() { /* ... */ }
void g() { /* ... */ }
};
extern template struct S<int>;
[ s.cpp
] (已修改)
template <>
void S<int>::g() { /* ... */ }
template struct S<int>;
但是,这样做会导致以下编译错误:
<source>:11:14: error: explicit specialization of 'g' after instantiation
void S<int>::g() { /* ... */ }
^
<source>:8:23: note: explicit instantiation first required here
extern template class S<int>;
^
我认为发生错误是因为extern template
仍然被认为是一个 * 示例化 *,即使它只是一个声明。
如何通过在S
的面向客户端的头文件中提供extern template
声明,同时在源文件中保留S<int>::g
的显式专用化,来实现可能的编译加速?
1条答案
按热度按时间w6lpcovy1#
也在头中声明显式的专门化。
提炼规则:在实体成为显式示例化(定义或声明)的主体之前,必须出现显式专门化的声明。因为
S<int>
的显式示例化递归地构成S<int>::g
的相同内容,所以需要提前声明专门化。但我们应该庆幸我们没有着火。