当两个模板参数类型相同时如何进行偏特化?

How to perform partial specialisation when two template parameters are of the same type?

如何偏特化两个模板参数是同一类型。

如何使用第二个函数制作此代码。

#include <utility>
#include <iostream>

template <typename A, typename B>
void Translate(A&& a,B* b){
  // make some translate from a to b
  // b->bvalue=a.av;
  std::cout<<"normal function";
}
//if a and b are same type,
template <typename A>
void Translate(A&& a, A* b) {
  *b = std::forward<A>(a);
  std::cout<<"forward function";
}

int main(int argc, char** argv) {
  int in=0,out=0;
  Translate(in,&out);
  return 0;
}

预计输出 "forward function"。

您需要为第一个参数传入一个右值。以下两个打印 "forward function".

Translate(0, &out);
// or
Translate(std::move(in), &out);

使用 Translate(in, out),第二个重载无法一致地推导出 A 类型:第一个参数推导为 int&,而第二个参数推导为 int .

main.cpp:12:6: note: candidate: 'template<class A> void Translate(A&&, A*)'
 void Translate(A&& a, A* b) {
      ^~~~~~~~~
main.cpp:12:6: note:   template argument deduction/substitution failed:
main.cpp:19:21: note:   deduced conflicting types for parameter 'A' ('int&' and 'int')
   Translate(in, &out);

所以编译器求助于第一个重载。

问题是第二版根本调用不了。您将第一个参数声明为 fowarding reference,当传递 lvlaue A 时,将推导为 T&。那么第一个参数A会被推导为int&,第二个参数A会被推导为int,两者冲突

您可以使用 std::remove_reference for type adjustment. And to solve the following ambiguity issue you can use SFINAE,从重载集中排除不需要的特化。

// if A and B are different types
template <typename A, typename B>
std::enable_if_t<!std::is_same_v<std::remove_reference_t<A>, B>> Translate(A&& a,B* b){
  ...
}

// if they're the same type (as A) 
template <typename A>
void Translate(A&& a, std::remove_reference_t<A>* b) {
  ...
}

LIVE

顺便说一句:函数模板不能部分特化;正如您的代码所示,它们只能被重载。