C++ 类中定义的友元函数模板是否可用于查找?铿锵++;和g++;不同意

C++ 类中定义的友元函数模板是否可用于查找?铿锵++;和g++;不同意,c++,templates,c++11,friend,function-templates,C++,Templates,C++11,Friend,Function Templates,代码如下: struct foo { template<typename T = void> friend foo f() { return {}; } }; int main() { auto x = f(); // clang++ can't find it, g++ can. } g++4.9.0编译了它,但我认为它不应该有。这是一个相关的问题,但没有明确的答案。第15.4.2/2,4节对此进行了讨论,但他们都没有提出任何建议,即类中定义的友元函数模板应具有与类

代码如下:

struct foo {
  template<typename T = void>
  friend foo f() { return {}; }
};

int main() {
  auto x = f(); // clang++ can't find it, g++ can.
}
g++4.9.0编译了它,但我认为它不应该有。这是一个相关的问题,但没有明确的答案。第15.4.2/2,4节对此进行了讨论,但他们都没有提出任何建议,即类中定义的友元函数模板应具有与类中定义的非模板友元函数不同的可见性

这对我来说只是学术上的兴趣,尽管它确实是由可能有实际用例的其他人提出的问题引起的


在我看来,这像是一个g++错误。

是的,这是一个错误。我很惊讶它能找到这个函数。显然,GCC无法完全隐藏函数模板

此C++03示例也可编译,因此它可能是一个回归:

struct foo {
  template<typename T >
  friend void f( T ) { }

};

int main() {
  f( 3 ); // clang++ can't find it, g++ can.
}
structfoo{
模板
友元空f(T){}
};
int main(){
f(3);//g++找不到它,g++可以。
}

看起来g++错了,是的。我还认为g++是错误的。我只是想看看是否有其他人对标准中的段落的理解与我不同,或者标准中是否有我遗漏的段落。我看到一些人用它来用函数替换方法。它们使用类作为作用域,这是一个有效的技巧,但是您必须在
定义之外重新声明函数[template]。(更好的方式是使用
名称空间
使用
声明。)@yngum:这样做的动机是什么?为什么不使用名称空间?我想到的一种可能性是利用部分专门化。它(显然)在没有默认模板arg的情况下也会被破坏。(我将进行编辑以澄清这一点。)如果不是模板,则g++无法按预期找到它。@user3521733不用担心,我已经尝试过并更新了答案。
struct foo {
  template<typename T >
  friend void f( T ) { }

};

int main() {
  f( 3 ); // clang++ can't find it, g++ can.
}