template<class T>
class foo
{
public:
template<typename other>
void f(const other &val) { ... } // [1]template<>
void f(const T &val) { ...} // [2]
};
[2] будет являться полной или же частичной специализацией [1]? Можно ли вообще специализировать прямо в классе или нужно выносить отдельно?
Спасибо заранее.
Здравствуйте Sergey, Вы писали:
O>>[2] будет являться полной или же частичной специализацией [1]? Можно ли вообще специализировать прямо в классе или нужно выносить отдельно?
S>Полной. Только перед T вроде typename писать полагается.
Если можно, обоснование. Я тоже думаю, что полной, но вот хотелось бы быть 100% уверенным.
O>[2] будет являться полной или же частичной специализацией [1]?
Согласно текущей версии стандарта это является ошибкой, т.к. шаблон члена шаблона класса не может быть специализирован без специализации шаблона содержащего класса (14.7.3/18).
O>Можно ли вообще специализировать прямо в классе или нужно выносить отдельно?
Шаблоны членов класса должны специализироваться вне тела класса (14.7.3/2).
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте orangy, Вы писали:
O>>>[2] будет являться полной или же частичной специализацией [1]? Можно ли вообще специализировать прямо в классе или нужно выносить отдельно?
S>>Полной. Только перед T вроде typename писать полагается. O>Если можно, обоснование. Я тоже думаю, что полной, но вот хотелось бы быть 100% уверенным.
Таки я соврал. Это вообще не специализация.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
O>>[2] будет являться полной или же частичной специализацией [1]?
ПК>Согласно текущей версии стандарта это является ошибкой, т.к. шаблон члена шаблона класса не может быть специализирован без специализации шаблона содержащего класса (14.7.3/18).
Явно специализирован не может быть. К частичной специализации это не относится (см. пример в 14.5.4.3/2). Потому это и бросатеся в глаза как дефект, что для явной и частичной специализации заведены разные правила без каких-либо разумных оснований.
O>>Можно ли вообще специализировать прямо в классе или нужно выносить отдельно?
ПК>Шаблоны членов класса должны специализироваться вне тела класса (14.7.3/2).
Опять же, это относится только к явной специализации.
В данном примере, конечно, имеет место явная специализация, поэтому, согласно, текущему стандарту, пример ошибочен.
Здравствуйте Андрей Тарасевич, Вы писали:
АТ>бросатеся в глаза как дефект, что для явной и частичной специализации заведены разные правила без каких-либо разумных оснований. <...> В данном примере, конечно, имеет место явная специализация, поэтому, согласно, текущему стандарту, пример ошибочен.
Это мы правильно делаем, что все время повторяем "в текущем стандарте" т.к. в следующей версии, скорее всего, это поправят; во всяком случае, будем надеяться.
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
O>>>[2] будет являться полной или же частичной специализацией [1]?
АТ>В данном примере, конечно, имеет место явная специализация, поэтому, согласно, текущему стандарту, пример ошибочен.
Как это может быть явной специализацией, если тип Т не задан?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте Павел Кузнецов, Вы писали:
ПК>Это мы правильно делаем, что все время повторяем "в текущем стандарте" т.к. в следующей версии, скорее всего, это поправят; во всяком случае, будем надеяться.
<...>
S>Как это может быть явной специализацией, если тип Т не задан?
Специализацией это является, потому что присутствует `template<>'. Отсутствие в объявлении специализированной функции `<T>' в данном случае (если бы можно было предоставлять явную специализацию шаблонов членов в теле шаблона класса) допустимо, т.к. согласно п. 14.7.3/11 "A trailing template-argument can be left unspecified in the template-id naming an explicit function template specialization provided it can be deduced from the function argument type."
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
O>Под конструктор копирования это подходит если U == T ?
Сам себе и отвечаю:
12.8.2 (сноска 106)
Because a template constructor is never a copy constructor, the presence of such a template does not suppress the implicit declaration
of a copy constructor. Template constructors participate in overload resolution with other constructors, including copy constructors,
and a template constructor may be used to copy an object if it provides a better match than other constructors.
ПК><...>
S>>Как это может быть явной специализацией, если тип Т не задан?
ПК>Специализацией это является, потому что присутствует `template<>'.
Это не довод. Наличие template<> с тем же успехом может говорить, например, о синтаксической ошибке. В данном случае оно, IMHO, говорит только о том, что автор кода хотел, чтобы это было специализацией.
ПК>Отсутствие в объявлении специализированной функции `<T>' в данном случае (если бы можно было предоставлять явную специализацию шаблонов членов в теле шаблона класса) допустимо, т.к. согласно п. 14.7.3/11 "A trailing template-argument can be left unspecified in the template-id naming an explicit function template specialization provided it can be deduced from the function argument type."
Ну и где здесь "can be deduced from the function argument type"? Типа аргумента-то нет, в отличие от примера в процитированном пункте стандарта.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте orangy, Вы писали:
O>А есть где-нибудь список "планируемых" исправлений для стандарта после immutability period?
Все зависит от того, что ты понимаешь под `immutability period'. Если ты имеешь в виду пятилетний period of stability (который уже истек), т.е. ожидаемые изменения стандарта, то их, естественно, еще никто не знает. Какие-то догадки можно делать, например, на основании дискуссий в comp.std.c++.
Если же ты имеешь в виду исправления, которые войдут в Technical Corrigenda, то Andrew Koenig где-то сообщал, что TC1 уже направлен в ANSI/ISO для утверждения и его можно ожидать в течение нескольких месяцев. Один из последних черновиков доступен: http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1316.
O>Дефект лист я видел только для STL <...> А для языка есть в публичном доступе?
Здравствуйте Sergey, Вы писали:
ПК>>Отсутствие в объявлении специализированной функции `<T>' в данном случае (если бы можно было предоставлять явную специализацию шаблонов членов в теле шаблона класса) допустимо, т.к. согласно п. 14.7.3/11 "A trailing template-argument can be left unspecified in the template-id naming an explicit function template specialization provided it can be deduced from the function argument type."
S>Ну и где здесь "can be deduced from the function argument type"?
Чем изначальный пример в отношении специализации (кроме того, что она в нем не разрешена) отличается от следующего?
Здравствуйте Sergey, Вы писали:
ПК>>Отсутствие в объявлении специализированной функции `<T>' в данном случае (если бы можно было предоставлять явную специализацию шаблонов членов в теле шаблона класса) допустимо, т.к. согласно п. 14.7.3/11 "A trailing template-argument can be left unspecified in the template-id naming an explicit function template specialization provided it can be deduced from the function argument type."
S>Ну и где здесь "can be deduced from the function argument type"?
Чем изначальный пример в отношении специализации (кроме того, что она в нем не разрешена) отличается от следующего?
Здравствуйте Павел Кузнецов, Вы писали:
ПК>Здравствуйте Sergey, Вы писали:
ПК>>>Отсутствие в объявлении специализированной функции `<T>' в данном случае (если бы можно было предоставлять явную специализацию шаблонов членов в теле шаблона класса) допустимо, т.к. согласно п. 14.7.3/11 "A trailing template-argument can be left unspecified in the template-id naming an explicit function template specialization provided it can be deduced from the function argument type."
S>>Ну и где здесь "can be deduced from the function argument type"?
ПК>Чем изначальный пример в отношении специализации (кроме того, что она в нем не разрешена) отличается от следующего?
ПК>
Здравствуйте Sergey, Вы писали:
S>Это template type parameter класса foo, а не тип.
Ага... Так бы и формулировал с самого начала, а не в партизанов игрался В таком ракурсе давай сначала и по порядку:
S>>>Как это может быть явной специализацией, если тип Т не задан?
ПК>>Специализацией это является, потому что присутствует `template<>'.
S>Это не довод. Наличие template<> с тем же успехом может говорить, например, о синтаксической ошибке. В данном случае оно, IMHO, говорит только о том, что автор кода хотел, чтобы это было специализацией.
Это уже философский вопрос, чего хотел автор. Для компилятора важно, что получилось. Синтаксически `template < > declaration' (14.7.3), [2] является явной специализацией. О семантике (времени компиляции в т.ч.) программ, содержащих диагностируемые ошибки рассуждать бессмысленно. Например, следуя предложенной тобой логике, в частности, можно сформулировать, например, такие (в той же степени истинные) утверждения:
1) foo не является шаблоном класса, т.к. тело шаблона содержит ошибку;
2) f не является шаблоном члена шаблона класса, т.к. foo не является шаблоном класса (т.к. 1);
3) template<> void f(const T &val) не является специализацией шаблона класса, т.к. содержит как минимум две ошибки: подобная специализация не разрешена в теле шаблона класса и без явной специализации включающего шаблона класса
и т.д.
ПК>>>>14.7.3/11 "A trailing template-argument can be left unspecified in the template-id naming an explicit function template specialization provided it can be deduced from the function argument type."
S>>>Ну и где здесь "can be deduced from the function argument type"?
<...> S>>>Типа аргумента-то нет, в отличие от примера в процитированном пункте стандарта.
ПК>>Тип аргумента T.
S>Это template type parameter класса foo, а не тип.
Шаблон класса порождает множество несвязанных классов, в каждом из которых template type parameter привязан к соответствующему template type argument, который является каким-то типом. Поэтому я и написал аргумента T. Например:
template<class T>
class C
{
T t;
};
Следуя твоей логике можно было бы задать вопрос: "какого типа переменная t?". Да никакого, до тех пор, пока шаблон C не будет конкретизирован и template type parameter не будет привязан к какому-либо template type argument. Точно так же и в приведенном примере шаблона foo T обозначает какой-то тип. Выяснять какой бессмысленно до тех пор, пока шаблон foo не конкретизирован и template type parameter не привязан к template type argument. Когда это произошло, T обозначает тип соответствующего template type argument.
До тех же пор стандартом требуется, чтобы члены шаблона не порождались и, соответственно, подавляются всякие семантические проверки типа "provided it can be deduced from the function argument type", кроме тех, которые будут приводить к ошибкам при любых аргументах шаблона. Например, аналогично есть требование о том, что тип переменной должен быть законченным, или что два перегруженных метода класса должны иметь разные сигнатуры (т.е. разные соглашения о вызовах и/или типы аргументов и/или константность и т.п.). Однако эти правила в общем случае не могут быть проверены для членов шаблона класса:
template<class T>
class C
{
void f(int);
void f(T);
T t;
};
поэтому проверка этих правил откладывается до конкретизации шаблона, а компилятор ограничивается проверкой синтаксиса.
В примере шаблона foo с синтаксисом все в порядке. Поэтому, если бы не явные запреты, то исходный пример был бы верен, т.к. явная специализация функции-члена f порождалась бы, как и другие члены шаблона только при ее использовании. Я не вижу причин, почему компилятор не смог бы вывести необходимую информацию без `<T>' аналогично другим подобным случаям.
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен