【问题标题】:Friend explicit specialization of function template and ADL函数模板和 ADL 的友元显式特化
【发布时间】:2016-07-15 18:45:50
【问题描述】:

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

【问题讨论】:

  • 你的意思是first::foo&lt;int&gt; f;
  • 我认为这段代码无效。我得到“错误:在朋友声明中定义显式专业化'func1'”。 coliru.stacked-crooked.com/a/728b83afb9b416a4
  • 代码不应该编译,你用的是什么编译器?

标签: templates c++14 template-specialization


【解决方案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.

【讨论】:

  • 我相信你的第一个例子格式不正确,ndr。
  • 谢谢,将朋友声明参数与模板类参数分开使其工作。
  • @Barry,是的,它是部分的,但是将部分“func1”更改为“func1”并保持其他部分不变,解决“没有部分专业化错误”的问题是这就是你所指的。
【解决方案2】:

您无需提供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> >
};

【讨论】:

  • “但是你不能在类主体中定义一个特化”。 @Barry如果您查看第一个场景,则使用 foo& 而不是 foo& 进行专业化,并且编译失败,因为它在链接时找不到“cout”,但是如果您使用“printf”编译成功并选择友元特化。
  • @xhamr 1) 这不是编译失败,而是链接器错误 2) 由于显式专业化,代码应该无法编译......或者至少会有 ODR 问题。超载的方式更简单。
  • @xhamr 抱歉,编译不一定会失败。见[temp.expl.spec]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-04
  • 1970-01-01
  • 2013-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多