It'n known that friend function defined in class scope can be found via argument-dependent lookup so we have to use class type in friend function type, but if we define friend function outside of class it function parameters can be left empty. So how this works for template friends, if we have specialization outside of class it should be visible as ordinary friend function defined outside of class scope.
#include <iostream>
class A
{
public:
A()
: x(20)
{}
template <typename T>
friend void foo()
{
std::cout << "Primary Template" << std::endl;
}
friend void goo();
private:
int x;
};
void goo()
{
std::cout << "some goo" << std::endl;
}
template <>
void foo<int>()
{
std::cout << "specialization" << std::endl;
}
int main()
{
A a;
foo<int>(); // VS 2012 gives error C3767: 'foo': candidate function(s)
// not accessible
// 'foo' [may be found via argument-dependent lookup]
goo(); // OK
}
So why goo is visible and accessible but foo's specialization for int not? VisualStudio 2012 gives error "'foo': candidate function(s) not accessible, 'foo' [may be found via argument-dependent lookup]". By the way GCC compiles code without errors. Is there any restrictions in standard or this is just compilers issues?