为什么ADL没有选择部分特化?
template<class T>
void func1(T&){ // selected
...
}
namespace first{
template<class R>
struct foo{
friend void func1<>(foo<R>&){ // expected
cout << "foo.func1" <<endl;
}
};
}
foo<int> f;
func1(f);
答案 0 :(得分:1)
模板参数与朋友声明无关。您需要在friend
声明中明确说明这些内容:
template<class R>
struct foo{
template<typename U>
friend void func1<U>(foo<U>&){
cout << "foo.func1" <<endl; // cat();
}
};
同样对于您的情况,您应该决定,如果您想将朋友定义内联如上,或者只是提供声明:
template<class R>
struct foo{
template<typename U>
friend void ::func1<U>(foo<U>&);
};
后者应该明确地匹配全局命名空间中的friend
模板函数,并且可以根据需要进行专门化:
template<>
void func1(int&){
// ...
}
template<>
void func1(std::string&){
// ...
}
// a.s.o.
答案 1 :(得分:1)
您不需要提供func1
的专业化。只是提供一个过载:
namespace first {
template <class R>
struct foo {
friend void func1(foo& ){
std::cout << "foo.func1" << std::endl;
}
};
}
int i;
first::foo<int> f;
func(i); // calls ::func<int>
func1(f); // calls first::func1(first::foo<int>& );
否则,您可以指定一个项目,但您无法在课程正文中定义专业化:
template <class R>
struct foo {
friend void func1<>(foo& ); // friends ::func1<foo<R> >
};