Странный GCC 'ожидал первичное выражение …' ошибка [дубликат]

5
задан Community 23 May 2017 в 11:46
поделиться

3 ответа

Когда зависимое имя используется для ссылки на вложенный шаблон, вложенное имя должно быть добавлено к ключевому слову template , чтобы помочь компилятору поймите, что вы имеете в виду вложенный шаблон, и правильно проанализируйте код

template <typename T>
void F(A<T> &a)
{
    a.template f<0>();
}

Внутри main имя a не зависит, поэтому вам не нужен дополнительный ] ключевое слово шаблона. Внутри F name a зависит, поэтому ключевое слово необходимо.

Это похоже на дополнительное ключевое слово typename при обращении к именам вложенных типов через зависимое имя. Просто синтаксис немного другой.

16
ответ дан 18 December 2019 в 09:47
поделиться

В первом случае компилятор думает, что вы имеете в виду ...

a.f < 0 ...gibberish....

Ответ Андрея исправляет это.

1
ответ дан 18 December 2019 в 09:47
поделиться

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

#include <iostream>

struct A { 
  template<typename T> 
  static A f(T) { 
    return A(); 
  } 

  template<typename T> operator T() { return T(); }
}; 

template<typename U> 
int g() { 
  U u;
  typedef A (*funcPtrType)(int());
  return !(funcPtrType)u.f < int() > (0); 
}

int main() {
  std::cout << g<A>() << std::endl;
}

Это выводит 0 при запуске без добавления ключевого слова шаблона . Если вы добавите ключевое слово перед f , оно выведет 1 .


Объяснение

Версия без ключевого слова анализируется как

funcPtrType temp1 = (funcPtrType)u.f; // taking func address
bool temp2 = !temp1;                  // temp2 == false
bool temp3 = temp2 < int();           // temp3 == false
bool temp4 = temp3 > (0);             // temp4 == false
return temp4;

И версия с ключевым словом анализируется как

A temp1 = u.template f < int() > (0);     // function call
funcPtrType temp2 = (funcPtrType) temp1;  // temp2 == 0
bool temp3 = !temp2;                      // temp3 == true
return temp3;

Обратите внимание, что temp2 является пустым указателем (создается return T ( ) ). Совершенно разные синтаксические разборы, и оба действительны! Это действительно нуждается в способе устранения неоднозначности, который заключается в вставке соответствующего ключевого слова template .

0
ответ дан 18 December 2019 в 09:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: