функция шаблона - ошибка проверки типа - c ++ - PullRequest
1 голос
/ 09 декабря 2011

У меня есть этот шаблон функции

template < class TParam >
bool greaterThan (TParam A, TParam B) {
  if (typeid(TParam) == typeid(string)) {   
    return A.compare(B) > 0;   <--------------- Error
  } else {
    return A > B;
  }
}

Но компилятор не позволит мне использовать это с int.

В указанном выше месте появляется ошибка компилятора, которая говорит:

Member reference base type 'int' is not a structure or union.

Оператор if не выполняется, если я вызываю функцию на int.

Я закомментировал это и проверил.Я не знаю, что не так.

Ответы [ 4 ]

2 голосов
/ 09 декабря 2011

Вы знаете, что вы не вызываете compare на int, но компилятор этого не делает: ваш if оценивается во время выполнения.

Поскольку string является единственным особым случаем в вашем шаблоне, попробуйте следующее:

template < class TParam >
bool greaterThan (TParam A, TParam B) {
    return A > B;
}
bool greaterThan(const string& a, const string& b) {
    return a.compare(b) > 0;
}
2 голосов
/ 09 декабря 2011

Когда TParam равно int, с этим:

A.compare(B)

Вы пытаетесь вызвать compare метод int. Такого метода не существует. Вам нужно специализация шаблона , чтобы вы могли заставить шаблон делать что-то особенное, когда тип является определенным типом:

template<class TParam>
bool greaterThan(TParam A, TParam B) {
    return A > B; // this will be called for any type except string because of
                  // our following specialisation
}

// make a specialisation for when the template parameter is string
template<>
bool greaterThan<string>(string A, string B) { 
   return A.compare(B) > 0;
}

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

Обратите внимание, что string имеет operator<, поэтому вам даже не нужно его специализировать, если вы этого не хотите, но это хорошая возможность узнать о специализации шаблонов.

1 голос
/ 09 декабря 2011

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

Во-первых, используя специализацию из greaterThan для строк:

template < class TParam >
bool greaterThan (TParam A, TParam B) {
  return A > B;
}

template<>
bool greaterThan< string > (string A, string B) {
  return A.compare(B) > 0;
}

Во-вторых, используя перегрузку из greaterThan для строк:

template < class TParam >
bool greaterThan (TParam A, TParam B) {
  return A > B;
}

bool greaterThan (string const & A, string const & B) {
  return A.compare(B) > 0;
}

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

Кроме того, со специализациями функция, выбранная компилятором, может иногда оказаться неожиданной. И поскольку шаблоны функций могут быть только явно специализированными (т.е. не частично специализированными), перегрузка предлагает все преимущества и ни один из недостатков, связанных со специализациями.

Для получения дополнительной информации см. " Почему бы не специализировать шаблоны функций? " Херба Саттера.

1 голос
/ 09 декабря 2011

Код шаблона генерируется во время компиляции, поэтому оператор if () еще не был выполнен.

Существует 2 решения для этого

a) предоставляют специализированную версию шаблона дляint's

b) Не используйте Compare () - и требуйте, чтобы структура / классы предоставляли оператор сравнения.

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