C++: typedef для template class'ов

Andbar

Вот такой код:
template <typename c>
class a
{
static c value;
};

typedef a<double> doublea;
double doublea::value = 1.25;

int main(void)
{
}
нормально собирается студией, но gcc выдаёт ошибку при сборке:
1.cc:8: error: too few template-parameter-lists
Если перед "double doublea::value = 1.25;" дописать "template<>", всё нормально собирается.
Вопрос следующий: зачем это нужно? И какой пример можно привести, в котором без "template<>" смысл кода будет другим?

margadon

чо-то мне так кажется, что студия налажала

Andbar

чо-то мне так кажется, что студия налажала
Я точно знаю, что студия в данном случае забивает на несовместимость со стандартом (кстати, компилятор Comeau внятно об этом сообщил, в отличие от gcc).
Мне просто интересно, какой смысл в этом... Раньше мне казалось, что подобные вещи существуют для того, чтобы не перепутать данную конструкцию с чем-то ещё. В данном случае я не могу придумать конструкции, которую можно было бы спутать с этой. Я даже не про typedef, а про:
template<> mytype mytemplate<myparam> static_var = ...;

trobak

[ Домыслы, стандарта не знаю ]
Видимо, компиляторы по разному решают, когда класс a<double> необходимо инстанциировать. Конструкция
  typedef a<double> doublea; 

- лишь сокращение, к инстанциации шаблона отношения не имеет (хотя 6-я вижуал студия думала иначе :) ).
Видимо, встретив определение члена a<double>::value, майкрософтовский компилятор решил, что пора бы уж заодно и класс a<double> инстанциировать. А гнушный компилятор решил, что это не порядок, поскольку класc a<double> не был инcтанциирован, а значит и объявления члена a<double>::value как бы не было. А магическое "template<>" и означает инстанциацию.
[/ Домыслы, стандарта не знаю ]
Интересно, а если для гнушного компилятора вставить строку
template<> class a<double>;   

перед
 double doublea::value = 1.25; 

то скомпилируется?

erotic

Интересно, а если для гнушного компилятора вставить строку
template_typedef.cpp:9: ошибка: invalid use of undefined type ‘class a<double>’
template_typedef.cpp:3: ошибка: declaration of ‘class a<double>’

Вообще правильно инстанциировать шаблон конструкцией
 template class a<double>; 

, но даже после этого строчка
 double doublea::value = 1.25; 

не компилируется без template<> в начале с той же ошибкой, что и в первом посте. Так что, похоже, дело тут не совсем в инстанцировании шаблона.

buka

typedef-ом ты компилятор не обманешь :3
«double doublea::value = 1.25;» — это определение члена явно специализированного a<double>, к твоему value оно не имеет никакого отношения
template <typename c>
class a
{
static c value; // 1
};

template<>
class a<double>
{
static double value; // 2
};

typedef a<double> doublea;
double doublea::value = 1.25; // определение 2

int main(void)
{
}

а вот «template<> double doublea::value = 1.25;» суть явная специализация члена еще не специализированного под дабл шаблона, которая потянет за собой автоштамповку a<double>
т.к. явный и автоматический a<double> исключают друг друга, спутать их невозможно
с и без «template<>» смысл всегда разный, а вот придумать пример, когда оба варианта компилятся, но с разным результатом мне влом

Andbar

с и без «template<>» смысл всегда разный, а вот придумать пример, когда оба варианта компилятся, но с разным результатом мне влом

Если в этот код добавить
template<> double doublea::value = 3.0;   
студия выдаёт:
error C2998: 'double a<double>::value' : cannot be a template definition

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