Частичные специализации для указателей и функций

#c #templates #generics #specialization

#c #шаблоны #обобщения #специализация

Вопрос:

Это фрагменты шаблона для метода less, который принимает в качестве входных данных два общих аргумента и возвращает результат bool

  • Первый шаблон является общим
  • Второй — явный тип специализации const char*
  • Третья частичная специализация для указателей

Как реализовать частичную специализацию для функций?

 template<typename T> //general form
class C{
    public: bool isLess(const Tamp; v1, const Tamp; v2){
        return v1<v2;
    }
};

template<> //explicit specialization for char*
class C<const char*>{
public: bool isLess(const char* v1, const char* v2){
    return strcmp(v1,v2) < 0;}
};

template <typename T> //partial specialization for pointers
class C<T*> {
public: bool isLess(T* v1, T* v2){return *v1 < *v2;}
};
//partial specialization for functions?
 

Комментарии:

1. В чем заключается ваш вопрос? Специализированными могут быть только классы, но статическая функция-член специализированного класса так же хороша, как и специализированная функция, не являющаяся членом.

2. Или вы имеете в виду, что хотите частично специализироваться C на подборе типов функций? (или типы указателей функций)

3. Попробуй… template <typename... Args, typename ReturnType> class C<ReturnType (Args...)>

Ответ №1:

Я думаю, вы хотите что-то более или менее похожее на следующее:

 template <typename R, typename... Args>
class C<R(*)(Args...)> {
    using func_ptr = R(*)(Args...);
    public: bool isLess(func_ptr l, func_ptr r) { return std::less<>{}(l, r); }
};
 

Ответ №2:

У вас нет частичной специализации для функций; вместо этого у вас есть перегрузки и std::enable_if<c, T> . Подсказка: вы можете иметь std::enable_if<c, T>::type для функции, которая возвращает T заданных c значений.

Ответ №3:

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

 #include <iostream>
#include <cstring>

template <class T> bool isLess(const T amp;v1, const T amp;v2) {
  std::cerr << "generaln";
  return v1 < v2;
}

bool isLess(const char *v1, const char *v2) {
  std::cerr << "strn";
  return strcmp(v1, v2) < 0;
}

template <typename T> bool isLess(T *v1, T *v2) {
  std::cerr << "pointern";

  return *v1 < *v2;
}

int main() {
  int x = 0;
  int y = 1;
  auto s1 = "hey";
  auto s2 = "there";
  std::cerr << isLess(x, y) << "n";
  std::cerr << isLess(s1, s2) << "n";
  std::cerr << isLess(amp;x, amp;y) << "n";
}
 

Вывод:

 general
1
str
1
pointer
1