Специализация
От: orangy Россия
Дата: 17.09.02 10:46
Оценка:
Вот в таком примере:
template<class T>
class foo 
{
public:
    template<typename other>
    void f(const other &val) { ... } // [1]
            
    template<>
    void f(const T &val) { ...} // [2]
};


[2] будет являться полной или же частичной специализацией [1]? Можно ли вообще специализировать прямо в классе или нужно выносить отдельно?
Спасибо заранее.
... << J 1.0 alpha 4 >>
"Develop with pleasure!"
Re: Специализация
От: Sergey Россия  
Дата: 17.09.02 10:50
Оценка:
Здравствуйте orangy, Вы писали:

O>Вот в таком примере:

O>
O>template<class T>
O>class foo 
O>{
O>public:
O>    template<typename other>
O>    void f(const other &val) { ... } // [1]
O>            
O>    template<>
O>    void f(const T &val) { ...} // [2]
O>};
O>


O>[2] будет являться полной или же частичной специализацией [1]? Можно ли вообще специализировать прямо в классе или нужно выносить отдельно?


Полной. Только перед T вроде typename писать полагается.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[2]: Специализация
От: orangy Россия
Дата: 17.09.02 11:07
Оценка:
Здравствуйте Sergey, Вы писали:

O>>[2] будет являться полной или же частичной специализацией [1]? Можно ли вообще специализировать прямо в классе или нужно выносить отдельно?


S>Полной. Только перед T вроде typename писать полагается.

Если можно, обоснование. Я тоже думаю, что полной, но вот хотелось бы быть 100% уверенным.
"Develop with pleasure!"
Re: Специализация
От: Павел Кузнецов  
Дата: 17.09.02 12:13
Оценка:
Здравствуйте orangy, Вы писали:

O>
O>template<class T>
O>class foo 
O>{
O>public:
O>    template<typename other>
O>    void f(const other &val) { ... } // [1]
O>            
O>    template<>
O>    void f(const T &val) { ...} // [2]
O>};


O>[2] будет являться полной или же частичной специализацией [1]?


Согласно текущей версии стандарта это является ошибкой, т.к. шаблон члена шаблона класса не может быть специализирован без специализации шаблона содержащего класса (14.7.3/18).

O>Можно ли вообще специализировать прямо в классе или нужно выносить отдельно?


Шаблоны членов класса должны специализироваться вне тела класса (14.7.3/2).
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[3]: Специализация
От: Sergey Россия  
Дата: 17.09.02 12:53
Оценка:
Здравствуйте orangy, Вы писали:

O>>>[2] будет являться полной или же частичной специализацией [1]? Можно ли вообще специализировать прямо в классе или нужно выносить отдельно?


S>>Полной. Только перед T вроде typename писать полагается.

O>Если можно, обоснование. Я тоже думаю, что полной, но вот хотелось бы быть 100% уверенным.

Таки я соврал. Это вообще не специализация.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[2]: Специализация
От: Андрей Тарасевич Беларусь  
Дата: 17.09.02 18:23
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>Здравствуйте orangy, Вы писали:


O>>
O>>template<class T>
O>>class foo 
O>>{
O>>public:
O>>    template<typename other>
O>>    void f(const other &val) { ... } // [1]
O>>            
O>>    template<>
O>>    void f(const T &val) { ...} // [2]
O>>};


O>>[2] будет являться полной или же частичной специализацией [1]?


ПК>Согласно текущей версии стандарта это является ошибкой, т.к. шаблон члена шаблона класса не может быть специализирован без специализации шаблона содержащего класса (14.7.3/18).


Явно специализирован не может быть. К частичной специализации это не относится (см. пример в 14.5.4.3/2). Потому это и бросатеся в глаза как дефект, что для явной и частичной специализации заведены разные правила без каких-либо разумных оснований.

O>>Можно ли вообще специализировать прямо в классе или нужно выносить отдельно?


ПК>Шаблоны членов класса должны специализироваться вне тела класса (14.7.3/2).


Опять же, это относится только к явной специализации.

В данном примере, конечно, имеет место явная специализация, поэтому, согласно, текущему стандарту, пример ошибочен.
Best regards,
Андрей Тарасевич
Re[3]: Специализация
От: Павел Кузнецов  
Дата: 18.09.02 03:33
Оценка:
Здравствуйте Андрей Тарасевич, Вы писали:

АТ>бросатеся в глаза как дефект, что для явной и частичной специализации заведены разные правила без каких-либо разумных оснований. <...> В данном примере, конечно, имеет место явная специализация, поэтому, согласно, текущему стандарту, пример ошибочен.


Это мы правильно делаем, что все время повторяем "в текущем стандарте" т.к. в следующей версии, скорее всего, это поправят; во всяком случае, будем надеяться.
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[3]: Специализация
От: Sergey Россия  
Дата: 18.09.02 07:03
Оценка:
Здравствуйте Андрей Тарасевич, Вы писали:

O>>>
O>>>template<class T>
O>>>class foo 
O>>>{
O>>>public:
O>>>    template<typename other>
O>>>    void f(const other &val) { ... } // [1]
O>>>            
O>>>    template<>
O>>>    void f(const T &val) { ...} // [2]
O>>>};


O>>>[2] будет являться полной или же частичной специализацией [1]?


АТ>В данном примере, конечно, имеет место явная специализация, поэтому, согласно, текущему стандарту, пример ошибочен.


Как это может быть явной специализацией, если тип Т не задан?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re: Специализация
От: Anton V. Kolotaev  
Дата: 18.09.02 07:08
Оценка:
Кстати, а что мешает написать

template<class T>
class foo 
{
public:
    template<typename other>
    void f(const other &val) { ... } // [1]
            
    void f(const T &val) { ...} // [2]
};
Re[4]: Специализация
От: orangy Россия
Дата: 18.09.02 07:21
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>Это мы правильно делаем, что все время повторяем "в текущем стандарте" т.к. в следующей версии, скорее всего, это поправят; во всяком случае, будем надеяться.


А есть где-нибудь список "планируемых" исправлений для стандарта после immutability period?
Дефект лист я видел только для STL (http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html)
http://std.dkuug.dk/jtc1/sc22/wg21/prot/14882fdis/cwg_active.html
А для языка есть в публичном доступе? (http://std.dkuug.dk/jtc1/sc22/wg21/prot/14882fdis/cwg_active.html здесь вроде оно, но закрыто)
... << J 1.0 alpha 4 >>
"Develop with pleasure!"
Re[4]: Специализация
От: Павел Кузнецов  
Дата: 18.09.02 07:50
Оценка:
Здравствуйте Sergey, Вы писали:

O>>>>
O>>>>template<class T>
O>>>>class foo 
O>>>>{
O>>>>public:
O>>>>    template<typename other>
O>>>>    void f(const other &val) { ... } // [1]
O>>>>            
O>>>>    template<>
O>>>>    void f(const T &val) { ...} // [2]
O>>>>};


<...>

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 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Специализация
От: orangy Россия
Дата: 18.09.02 08:17
Оценка:
Еще вопрос в ту же степь:

template<class T>
class foo 
{
public:
    template<typename U>
    void foo(const U &other) { ... } 
};

Под конструктор копирования это подходит если U == T ?
... << J 1.0 alpha 4 >>
"Develop with pleasure!"
Re[2]: Специализация
От: orangy Россия
Дата: 18.09.02 08:21
Оценка:
Здравствуйте orangy, Вы писали:

O>
O>template<class T>
O>class foo 
O>{
O>public:
O>    template<typename U>
O>    void foo(const U &other) { ... } 
O>};
O>

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.
... << J 1.0 alpha 4 >>
"Develop with pleasure!"
Re[5]: Специализация
От: Sergey Россия  
Дата: 18.09.02 08:22
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>Здравствуйте Sergey, Вы писали:


O>>>>>
O>>>>>template<class T>
O>>>>>class foo 
O>>>>>{
O>>>>>public:
O>>>>>    template<typename other>
O>>>>>    void f(const other &val) { ... } // [1]
O>>>>>            
O>>>>>    template<>
O>>>>>    void f(const T &val) { ...} // [2]
O>>>>>};


ПК><...>


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 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[5]: Специализация
От: Павел Кузнецов  
Дата: 18.09.02 08:28
Оценка:
Здравствуйте 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 <...> А для языка есть в публичном доступе?


Список дефектов для core language есть: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html.
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[6]: Специализация
От: Павел Кузнецов  
Дата: 18.09.02 08:42
Оценка:
Здравствуйте 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"?


Чем изначальный пример в отношении специализации (кроме того, что она в нем не разрешена) отличается от следующего?

typedef . . . T;

template<typename other>
void f(const other &val);

template<>
void f(const T& val);


последнее объявление эквивалентно такому:

template<>
void f<T>(const T& val);


S>Типа аргумента-то нет, в отличие от примера в процитированном пункте стандарта.


Тип аргумента T.
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[6]: Специализация
От: Павел Кузнецов  
Дата: 18.09.02 08:43
Оценка:
Здравствуйте 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"?


Чем изначальный пример в отношении специализации (кроме того, что она в нем не разрешена) отличается от следующего?

typedef . . . T;

template<typename other>
void f(const other &val);

template<>
void f(const T& val);


последнее объявление эквивалентно такому:

template<>
void f<T>(const T& val);


S>Типа аргумента-то нет, в отличие от примера в процитированном пункте стандарта.


Тип аргумента T.
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: Специализация
От: Sergey Россия  
Дата: 18.09.02 09:07
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>Здравствуйте 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"?


ПК>Чем изначальный пример в отношении специализации (кроме того, что она в нем не разрешена) отличается от следующего?


ПК>
ПК>typedef . . . T;

ПК>template<typename other>
ПК>void f(const other &val);

ПК>template<>
ПК>void f(const T& val);


Отсутствием typedef . . . T; в исходном примере.


S>>Типа аргумента-то нет, в отличие от примера в процитированном пункте стандарта.


ПК>Тип аргумента T.


Это template type parameter класса foo, а не тип.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[8]: Специализация
От: Павел Кузнецов  
Дата: 18.09.02 14:01
Оценка: 10 (1)
Здравствуйте 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 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[9]: Специализация
От: Павел Кузнецов  
Дата: 18.09.02 14:09
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>тип переменной должен быть законченным


Ох уж этот перевод терминов... следует читать полным.
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.