Как выполнить частичную специализацию, когда два параметра шаблона имеют одинаковый тип? - PullRequest
3 голосов
/ 14 июня 2019

Как частичная специализация, чтобы два параметра шаблона были одного типа.

Как создать этот код, используя вторую функцию.

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

Ожидается, что "вперед функция".

Ответы [ 2 ]

5 голосов
/ 14 июня 2019

Проблема в том, что 2-я версия не может быть вызвана вообще. Вы объявляете 1-й параметр как относительно ссылки , при пропуске lvlaue A будет выводиться как T&. Тогда для 1-го параметра A будет выведено как int&, для 2-го параметра A будет выведено как int, они конфликтуют.

Вы можете использовать std::remove_reference для настройки типа. И чтобы решить следующую проблему неоднозначности, вы можете использовать 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) {
  ...
}

ЖИТЬ

Кстати: шаблоны функций не могут быть частично специализированными; как показал ваш код, они могут быть перегружены.

1 голос
/ 14 июня 2019

Вам необходимо передать значение r для первого параметра.Обе следующие функции выдают «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);

Таким образом, компилятор прибегает к первой перегрузке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...