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

Viewed 59

How to partial specialization that two template parameter are same type.

How to make this code using second function .

#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;
}

Expect out put "forward function".

2 Answers

The problem is that the 2nd version can't be called at all. You're declaring the 1st parameter as fowarding reference, when being passed an lvlaue A will be deduced as T&. Then for the 1st parameter A will be deduced as int&, for the 2nd parameter A will be deduced as int, they conflict.

You can use std::remove_reference for type adjustment. And to solve the following ambiguity issue you can use SFINAE, to exclude undesired specializations from the overload set.

// 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

BTW: Function templates can't be partial specialized; as your code showed they can only be overloaded.

You need to pass in an rvalue for the first parameter. Both of the following print "forward function".

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

With Translate(in, out), the second overload can't deduce the A type consistently: the first parameter is deduced as int& while second parameter is deduced as 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);

So the compiler resorts to the first overload.

Related