模板类非模板友元函数含requires子句:GCC编译失败是否为Bug?
这是GCC的编译器Bug吗?
是的,这确实属于GCC的Bug,你的代码完全符合C++标准,应该被正确编译。
问题分析
- 模板类
base<Derived>中的非模板友元函数foo使用requires子句进行约束是C++标准允许的语法,这种约束可以基于参数的特性(这里依赖bar(d)的合法性)。 - 当
adl::S继承base<S>时,根据C++的友元注入规则,foo(S const&)会被注入到S所在的adl命名空间中。 - 在
test函数调用foo(s)时,**参数依赖查找(ADL)**应该能自动找到adl命名空间里的foo——因为参数s的类型是adl::S,ADL会搜索该类型所在的命名空间。
GCC在这里没有正确处理友元函数的注入与ADL查找,导致无法找到foo,而Clang和MSVC的行为是符合标准要求的。
可复现代码
template< typename Derived > struct base { friend void foo(Derived const& d) requires requires { bar(d); } { bar(d); } }; namespace adl { struct S: base<S> { friend void bar(S const&) {} }; } using adl::S; void test(S const& s) { foo(s); // gcc error: 'foo' was not declared in this scope }
内容的提问来源于stack exchange,提问作者wanghan02
相关产品推荐
相关产品推荐

