友元函数模板查找

friend function template lookup

按照标准,在class中声明和定义的友元函数只能通过ADL查找。所以,我认为下面的代码应该可以编译。

template<int M>
struct test{
    template<int N = 0>
    friend void foo(test){}
};

int main(){
    test<2> t;
    foo(t);// compile
    foo<1>(t);// error
}

但是,gcc 给出了以下错误:

main.cpp: In function 'int main()':

main.cpp:10:5: error: 'foo' was not declared in this scope

     foo<1>(t);

     ^~~

那么,我有3个问题。

  1. 应该template<int N> foo按标准找吗?
  2. 为什么找到 foo 而找不到 foo<1>
  3. 除了在外面定义 foo 之外,还有解决方法吗?

https://en.cppreference.com/w/cpp/language/adl

Although a function call can be resolved through ADL even if ordinary lookup finds nothing, a function call to a function template with explicitly-specified template arguments requires that there is a declaration of the template found by ordinary lookup (otherwise, it is a syntax error to encounter an unknown name followed by a less-than character) (until C++20)

在 C++20 模式下,您的代码可以正常编译,演示:https://gcc.godbolt.org/z/svdfW9drf