не членный оператор <() для вложенного класса шаблонного класса, не соответствующего компилятору - PullRequest
1 голос
/ 27 октября 2011

У меня проблема с оператором сравнения на основе шаблонов для сравнения экземпляров типа, зависящего от аргумента шаблона. Я некоторое время обыскивал трубки, в том числе SO, и изо всех сил пытался понять, что я делаю неправильно. Я считаю, что это проблема с поиском зависимых имен, но это не помогает мне заставить работать код: - (

Вот минимальный тестовый пример:

template<typename T>
struct Foo
{
  struct Bar {
     T t;
  };

  Bar b;
};


template<typename T>
inline bool operator<(const typename Foo<T>::Bar& b1, const typename Foo<T>::Bar& b2)
{ return b1.t < b2.t; }


int main()
{
  Foo<int> f1, f2;
  return (f1.b < f2.b?  0 : 1);
}

Компиляция дает:

templated-comparison-op.cpp: In function ‘int main()’:
templated-comparison-op.cpp:20:20: error: no match for ‘operator<’ in ‘f1.Foo<int>::b < f2.Foo<int>::b’
templated-comparison-op.cpp:20:20: note: candidate is:
templated-comparison-op.cpp:13:13: note: template<class T> bool operator<(const typename Foo<T>::Bar&, const typename Foo<T>::Bar&)

Пока у меня есть оператор сравнения в качестве члена класса шаблона, который работает нормально, поэтому без срочности. Я хотел бы понять, чего мне здесь не хватает; кто-нибудь может просветить меня?

Редактировать: Это не совсем точный тестовый пример; в реальном коде, из которого я извлек этот случай, шаблонный класс Foo вложен в другой класс, и поэтому необходимы ключевые слова 'typename'. Как указано в ответах ниже, в приведенном выше коде «typename» не понадобится.

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

Ответы [ 3 ]

3 голосов
/ 27 октября 2011

Вам не нужны typename s в объявлении функции, поскольку Foo<T> не является зависимым типом:

template<typename T>
bool operator<(const Foo<T>& f1, const Foo<T>& f2)
{ return f1.t < f2.t; }

(я не уверен, почему они вызывают эту конкретную ошибку, но удаление их исправляет это).

3 голосов
/ 29 октября 2011

Проблема в том, что ваш operator< не может использоваться, потому что компилятор не может автоматически определить, что такое T.

Вы можете решить свою проблему, объявив не шаблон operator<

template<typename T>
struct Foo
{
  struct Bar {
     T t;
  };

  Bar b;

  friend bool operator<(const Bar& b1, const Bar& b2)
  { return b1.t < b2.t; }
};

Объявление operator< затем определяется аргументно-зависимым поиском для operator< для выражения x < y.

В качестве альтернативы вы можете поместить определение operator< в определение Bar (но в данном случае это не имеет значения, поскольку Foo<T> является ассоциированным классом Foo<T>::Bar).

2 голосов
/ 27 октября 2011

Не знаю, в этом ли проблема, но typename в списке параметров не должно быть. ( Если проблема , это ужасное сообщение об ошибке.)

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