在类模板成员函数的显式特化存在的情况下使用“外部模板”时出错

问题描述 投票:0回答:2

考虑一个类模板

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>
的多次实例化来加快编译时间,我想在头文件extern template中引入一个
显式实例化声明
s.hpp
,以及相应的显式实例化定义在源文件
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
仍然被认为是一个实例化,甚至认为它只是一个声明。

如何通过在面向客户的头文件中为

extern template
提供
S
声明来实现可能的编译加速,同时仍然在源文件中保留
S<int>::g
的显式专业化?

c++ c++11 instantiation extern explicit-instantiation
2个回答
0
投票

在头文件中,用

idndef
指令包裹extern显式实例化声明,这样你就可以在提供显式实例化定义的翻译单元中抑制它。

s.hpp

/* definition of S unchanged */

#ifndef S_DO_NOT_INSTANTIATE
extern template struct S<int>;
#endif

s.cpp

#define S_DO_NOT_INSTANTIATE
#include "s.hpp"

/* remainder unchanged */

0
投票

也在标头中声明显式特化。

template <typename>
struct S
{
    void f() { /* ... */ }
    void g() { /* ... */ }
};

template <>
void S<int>::g();

extern template struct S<int>;

要提炼规则:显式特化的声明必须出现在实体是显式实例化(定义或声明)的主题之前。因为

S<int>
的显式实例化对
S<int>::g
递归构成相同,所以需要提前声明特化

但让我们庆幸的是我们没有着火.

© www.soinside.com 2019 - 2024. All rights reserved.