Есть ли способ (на С++) создать класс шаблона, реализующий определенные функции?

Я хочу создать класс, который принимает только определенные типы классов шаблонов. Я знаю, что существует специализация шаблонов, но я хочу, чтобы мой класс принимал все шаблоны, реализующие определенную функцию, поиск.

Скажем, у меня есть class A следующим образом:

template<class T> //add a restriction that T implements bool search(T)
class A
{
    T t;
    //do something that uses T.search(T x)
    if(t.search(x))
        //Do something
};

В общем, я хочу создать общий класс, который работает для всех классов, имеющих функцию поиска. Есть ли способ сделать это?


person Sahil Dhoked    schedule 24.01.2018    source источник
comment
Вам нужны концепции, которые (надеюсь) появятся в C++20. Между тем, это более или менее возможно сделать, но это будет не так чисто/просто. Каков ваш вариант использования?   -  person Synxis    schedule 25.01.2018
comment
У меня проблема с поиском, для которой у меня есть 5 разных решений. Я закодировал каждое решение в отдельном файле cpp. Теперь я хочу протестировать эти решения и сравнить их производительность, в частности я хочу протестировать функциональность поиска. Поэтому я создал общий тестовый класс, использующий функцию поиска. Что я хотел бы сделать, так это подключить имя класса каждого решения, и тест запускается сам по себе и дает мне результаты.   -  person Sahil Dhoked    schedule 25.01.2018
comment
T.search(x)? Не должно быть T::search(x) или что-то вроде T().search(x)? Кстати, ваш шаблон класса будет генерировать неправильно сформированный код, когда вы создадите его с помощью T не имеет функции-члена search. Это тоже своего рода ограничение.   -  person Francis    schedule 25.01.2018
comment
@Synxis: это уже может сделать SFINAE. Не надо концепций! Но на самом деле, концепции сделают это намного проще!   -  person Klaus    schedule 25.01.2018
comment
Если T не имеет функции поиска, то попытка использовать A‹T› не удастся скомпилировать. Какие еще ограничения вам потребуются?   -  person ROX    schedule 25.01.2018
comment
@ROX, так можно ли использовать поиск, не объявляя его в общем шаблоне?   -  person Sahil Dhoked    schedule 26.01.2018
comment
если T реализует поиск, все в порядке. Если вы попытаетесь использовать T, который не реализует поиск, вы получите ошибку времени компиляции. В C# вам нужно было бы объявить, что T имеет поиск, заявив, что он реализует определенный интерфейс (заранее объявленный как содержащий поиск), но вам не нужно делать то же самое для C++.   -  person ROX    schedule 26.01.2018


Ответы (1)


Я хочу создать общий класс, который работает для всех классов, имеющих функцию поиска. Есть ли способ сделать это?

Например, используя decltype() следующим образом

template <typename T,
          typename = decltype(std::declval<T>().search(std::declval<T>()))>
class A
 {
 };

Ниже приведен полный пример компиляции для size() включенного class A.

#include <string>
#include <type_traits>

template <typename T, typename = decltype(std::declval<T>().size())>
class A
 {
 };

int main()
 {
   A<std::string>  as;
   //A<int>          ai;  // compilation error
 }

В этом решении есть недостаток: его можно перехватить, объяснив второй параметр шаблона; Например, следующий код компилируется

A<int, void>  ai;

Чтобы избежать этой проблемы, вы можете использовать частичную специализацию следующим образом.

template <typename T,
          typename = decltype(std::declval<T>().search(std::declval<T>()))>
class A;

template <typename T>
class A<T>
 {
 };
person max66    schedule 24.01.2018