c ++ Установка equal_to в качестве аргумента шаблона по умолчанию для класса шаблона - PullRequest
1 голос
/ 04 мая 2020

Как именно вы должны установить обобщенный c класс в качестве аргумента шаблона по умолчанию? Мне удалось получить не обобщенные c классы для компиляции, но не обобщенные c.

using namespace std;
template <typename T, typename Cmp = std::equal_to<T> >
class CSearch
{
   public:
    CSearch(){
     MComp = equal_to<T>();
    }
    CSearch(Cmp compare){
     MComp = compare;

    }
    //more functions
   private:
    Cmp MComp;
    //more 
};

T - это любой тип данных с итератором

Предполагается, что Cmp быть функцией двоичного предиката / функтором / лямбда-функцией. Cmp вызывается так:

MComp(*it2,*it3);

Теперь с этой основной функцией работает код. Обратите внимание, что CharComparator на самом деле ничем не отличается от equal_to, за исключением того, что он не является универсальным c.

class CharComparator
{
  public:
               CharComparator ( bool caseSensitive = true )
      : m_CaseSensitive ( caseSensitive )
    {
    }
    bool       operator () ( const char & a, const char & b ) const
    {
      return m_CaseSensitive ? a == b : toupper (a) == toupper (b);
    }
  private:
    bool       m_CaseSensitive;
};
int main(){
CSearch <string, CharComparator> test3 ( CharComparator(false) );
//functions,calling Cmp
}

Но этот не компилируется, когда вызывается Cmp:

int main(){
CSearch <string> test1;
//functions,calling Cmp
}

Вот ошибка компилятора.

test.cpp: In instantiation of 'bool CSearch<T, Cmp>::SearchFragment(const T&, const T&) const [with T = std::__cxx11::basic_string<char>; Cmp = std::equal_to<std::__cxx11::basic_string<char> >]':
test.cpp:88:6:   required from 'std::set<int> CSearch<T, Cmp>::Search(const T&) const [with T = std::__cxx11::basic_string<char>; Cmp = std::equal_to<std::__cxx11::basic_string<char> >]'
test.cpp:130:3:   required from here
test.cpp:60:3: error: no match for call to '(const std::equal_to<std::__cxx11::basic_string<char> >) (const char&, const char&)'
   60 |   if(MComp(*it2,*it3)){
      |   ^~
In file included from /usr/include/c++/9.3/string:48,
                 from /usr/include/c++/9.3/bits/locale_classes.h:40,
                 from /usr/include/c++/9.3/bits/ios_base.h:41,
                 from /usr/include/c++/9.3/ios:42,
                 from /usr/include/c++/9.3/ostream:38,
                 from /usr/include/c++/9.3/iostream:39,
                 from test.cpp:5:
/usr/include/c++/9.3/bits/stl_function.h:355:7: note: candidate: 'constexpr bool std::equal_to<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::__cxx11::basic_string<char>]'
  355 |       operator()(const _Tp& __x, const _Tp& __y) const
      |       ^~~~~~~~
/usr/include/c++/9.3/bits/stl_function.h:355:29: note:   no known conversion for argument 1 from 'const char' to 'const std::__cxx11::basic_string<char>&'
  355 |       operator()(const _Tp& __x, const _Tp& __y) const
      |                  ~~~~~~~~~~~^~~

1 Ответ

2 голосов
/ 04 мая 2020

В этой строке ошибки указано, что не так:

error: no match for call to '(const std::equal_to<std::__cxx11::basic_string<char> >) (const char&, const char&)'

Вы пытаетесь вызвать экземпляр std::equal_to<std::string> для сравнения двух символов, но std::equal_to<std::string> сравнивает строки.

Вы хотите std::equal_to< typename T::value_type>, а не std::equal_to<T>, потому что вы сравниваете символы, а не строки (или вообще элементы, когда T является типом контейнера).

Также не следует назначать MComp = equal_to<T>(); в конструкторе по умолчанию. Если Cmp отличается от equal_to<T>, то конструктор по умолчанию работать не будет. Вместо этого вам следует инициализировать MComp экземпляром по умолчанию типа Cmp.

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