朋友明确的功能模板和ADL专业化

时间:2016-07-15 18:45:51

标签: templates c++14 template-specialization

为什么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);   

2 个答案:

答案 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> >
};