Какой компилятор прав? 'шаблон' перед шаблонным типом возвращаемого значения требуется? - PullRequest
15 голосов
/ 04 июня 2011

Этот фрагмент (взятый из этого вопроса ) прекрасно компилируется с g ++ (как видно), так что до template до появления возвращаемого типа. Напротив, VC10 не компилирует этот код со следующей ошибкой:

ошибка C2244: 'A :: getAttr': невозможно сопоставить определение функции с существующим объявлением

Если я удаляю template, VC10 доволен, но g ++ выдает эту ошибку:

ошибка: не шаблон 'AttributeType' используется в качестве шаблона
примечание: используйте «A :: template AttributeType», чтобы указать, что это шаблон

Это снова из-за неправильного двухфазного поиска в ВХ или в чем причина? Какой компилятор прямо здесь? Я подозреваю, что g ++ верен, так как у меня здесь требуется неопределенная память template, как с шаблоном rebind внутри распределителей.


Редактировать : У нас есть победитель: g ++ / GCC (неожиданный сюрприз ...).


template <typename T, typename K>
class A {
public:
    T t;
    K k;

    template <int i, int unused = 0>
    struct AttributeType{
    };

    template <int i>
    AttributeType<i> getAttr();

};

template <typename T, typename K>
template <int i>
typename A<T, K>::template AttributeType<i> A<T, K>::getAttr() {
//                ^^^^^^^^ -- needed or not?
    return t;
}


int main(){
    A<int,int> a;
}

1 Ответ

10 голосов
/ 04 июня 2011

GCC правильно. AttributeType является зависимым именем шаблона, за которым следует угловая скобка <, поэтому здесь необходимо ключевое слово template, чтобы устранить неоднозначность 1 , давая понять компилятору, что следует это имя шаблона. Правило упоминается в §14.2 / 4:

Когда имя члена шаблона специализация появляется после. или -> в постфиксном выражении или после спецификатор вложенного имени в квалифицированный идентификатор, а Постфиксное выражение или уточненный идентификатор явно зависит от шаблон-параметр (14.6.2), имя шаблона участника должно быть префиксом по шаблону ключевого слова. В противном случае имя предполагается, чтобы назвать нешаблонном.

1 @ Йоханнес написал очень хорошее объяснение здесь:

Где и почему я должен поставить ключевые слова "template" и "typename"?

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