Friend 显式特化函数模板和 ADL
Friend explicit specialization of function template and ADL
为什么下面的偏特化没有被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);
模板参数与友元声明无关。您需要在 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.
您无需提供 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>& );
否则,您可以将专业化加为好友,但不能在 class 正文中定义专业化:
template <class R>
struct foo {
friend void func1<>(foo& ); // friends ::func1<foo<R> >
};
为什么下面的偏特化没有被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);
模板参数与友元声明无关。您需要在 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.
您无需提供 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>& );
否则,您可以将专业化加为好友,但不能在 class 正文中定义专业化:
template <class R>
struct foo {
friend void func1<>(foo& ); // friends ::func1<foo<R> >
};