当显式模板实例化定义先于显式声明时,GCC 和 clang 不同意

When explicit template instantiation definition precedes explicit declaration, GCC and clang disagree

见以下代码:

#include <vector>

template class std::vector<int>;
extern template class std::vector<int>;

int main() {}

虽然 GCC 5.2 编译正常,但 clang 3.6 给出以下错误消息:

main.cpp:4:28: error: explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')
extern template class std::vector<int>
                           ^
main.cpp:3:21: note: explicit instantiation definition is here
template class std::vector<int>
                    ^
1 error generated.

仍然,对于下面的代码

template <typename T>
void f() {}

template void f<int>();
extern template void f<int>();

int main() {}

GCC 和 clang 都出错了。 GCC 的消息是

main.cpp:5:29: error: duplicate explicit instantiation of 'void f() [with T = int]' [-fpermissive]
 extern template void f<int>();

而 clang 的是

main.cpp:5:22: error: explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')
extern template void f<int>();
                     ^
main.cpp:4:15: note: explicit instantiation definition is here
template void f<int>();
              ^
1 error generated.

这两个人是怎么回事?标准是否禁止显式模板实例化声明之前有显式定义?这对我来说没什么意义。毕竟,先定义再声明有什么害处呢?想想非模板函数的情况。

来自 [temp.explicit] / 11

If an entity is the subject of both an explicit instantiation declaration and an explicit instantiation definition in the same translation unit, the definition shall follow the declaration.

GCC 也应该为第一个示例提供错误。

相关bug从2008年开始,GCC检测错误好像有问题类,下面也漏了

template <typename T> class f {};

template class f<int>;
extern template class f<int>;

int main() {}