【发布时间】:2019-12-19 19:42:18
【问题描述】:
在template class 中实现template friend function 的问题在过去已经讨论过,并且似乎是an unresolved issue in the standard 具有不同编译器的不同行为。
检查 gcc 和 clang 的最新可用版本,似乎已做出决定,要求 template friend function 的实现在 外部 的template class。
以下代码在编译时被最新版本的 gcc 和 clang(gcc x86-64 9.2.0 和 clang x86-64 9.0.0)拒绝-std=c++2a。 clang 的过去版本都可以使用(例如 clang x86-64 7.0.0)。
template<long Num>
struct A {
template<long Num1, long Num2>
friend int foo(A<Num1> a1, A<Num2> a2) {
return 1;
}
// the compilation error occurs only with a template friend function
// and only if *implemented inside* a template class
};
int main() {
A<1> a1;
A<2> a2; // commenting this line removes the error
}
两个编译器都抱怨 foo 的重新定义:
<source>:4:16: error: redefinition of 'foo'
friend int foo(A<Num1> a1, A<Num2> a2) {
^
<source>:11:10: note: in instantiation of template class 'A<2>' requested here
A<2> a2;
^
是否有关于该主题的新官方决议,还是只是最新的编译器时尚?
【问题讨论】:
-
问题 2174 已在 C++17 中解决:open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2174
-
@NathanOliver 这似乎是答案。它破坏了用于在 clang 中编译的旧代码,但规则是好坏参半的规则:-/
-
@NathanOliver-ReinstateMonica 我不明白这一点。如果问题的解决方案是定义仅在需要定义存在的上下文中引用时才被实例化 - 为什么这意味着 OP 的代码格式错误?我没有看到
foo的任何用法,所以我根本不明白为什么它的定义需要实例化。你能写一个你可以详细说明的答案吗? -
@Brian 我自己也不确定。我只是指出,上一篇文章中的至少一个问题已经解决。模板实例化规则仍然困扰着我。
标签: c++ templates language-lawyer friend