Определение типа при создании экз. шаблонного класса
От: RobinBobin  
Дата: 25.05.04 07:36
Оценка:
Привет, всем!

Возник такой вопрос: почему компилятор не может вывести тип при создании экземпляра шаблонного класса так же, как он делает при вызове шаблонной функции?

template <class TYPE>
struct ARRAY
{
   TYPE     *pArray;
   DWORD    dwSize;

   ARRAY(TYPE *array, DWORD size)
   {
      pArray = array; dwSize = size;
   }
};

BYTE byte_buf[] = {10, 20, 30};
ARRAY arr(byte_buf, 3); // Ошибка!!!


Как только пишу
ARRAY <BYTE> arr(byte_buf, 3)

всё замечательно.

Ведь можно же написать:
template <class TYPE>
void func(TYPE obj);


И потом вызвать:
func(10);
Re: Определение типа при создании экз. шаблонного класса
От: Vamp Россия  
Дата: 25.05.04 07:49
Оценка:
А потому, что конструктор может быть совершенно любой. И только в одном конкретном случае — когда одним из аргументов конструктора является переменная типа шаблона, можно выполнить автоматическое выведение. Ты хочешь, чтобы компилятор внимательно изучал сигнатуру конструктора и смотрел, не принимает ли он какой-нибудь параметр шаблонного типа? Этого не будет.
Да здравствует мыло душистое и веревка пушистая.
Re: Определение типа при создании экз. шаблонного класса
От: Аноним  
Дата: 25.05.04 07:49
Оценка:
А как быть с конструктором по умолчанию? А как быть с конструктором шаблоном? А как быть с конструктором, который выводит не все типы? Далее, YourMegaFicha a(10); YourMegaFicha b(10.) как пользователь твоей программы должен будет различать, а и b одного типа или нет?
Re: Определение типа при создании экз. шаблонного класса
От: Juny Россия  
Дата: 25.05.04 07:50
Оценка: 3 (1)
Здравствуйте, RobinBobin, Вы писали:

RB>Возник такой вопрос: почему компилятор не может вывести тип при создании экземпляра шаблонного класса так же, как он делает при вызове шаблонной функции?


Я тут Страуструпа читал....

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


То есть, объект класса можно создать очень по-разному, и создатели языка побоялись неоднозначностей и запутанностей, которые могут из-за этого возникнуть.
Re[2]: Определение типа при создании экз. шаблонного класса
От: RobinBobin  
Дата: 25.05.04 07:51
Оценка:
Здравствуйте, Vamp, Вы писали:

V>А потому, что конструктор может быть совершенно любой. И только в одном конкретном случае — когда одним из аргументов конструктора является переменная типа шаблона, можно выполнить автоматическое выведение. Ты хочешь, чтобы компилятор внимательно изучал сигнатуру конструктора и смотрел, не принимает ли он какой-нибудь параметр шаблонного типа? Этого не будет.


Да, хочу .
Re[2]: Определение типа при создании экз. шаблонного класса
От: RobinBobin  
Дата: 25.05.04 07:54
Оценка: 7 (1)
Здравствуйте, Juny, Вы писали:

J>Я тут Страуструпа читал....


J>

J>Обратите внимание, что параметры шаблона класса(в отличие от шаблона функции) никогда не выводятся. Причина заключается в том, что гибкость, обеспечиваемая наличием нескольких конструкторов класса, во многих случаях является непреодолимым препятствием на пути такого выведения, и еще в большем числе случаев выведение неоднозначно.


Супер! Спасибо! К сожалению, Страуструпа не было под рукой . Дома есть, а на работе нет. Все тащить лень .

Robin
Re[3]: Определение типа при создании экз. шаблонного класса
От: Lorenzo_LAMAS  
Дата: 25.05.04 07:59
Оценка:
RB>Да, хочу .

Так Бог в помощь. Напиши свой компилятор, продемонстрируй достоинства твоего расширения и пиши в комитет по расширениям языка.
Of course, the code must be complete enough to compile and link.
Re[4]: Определение типа при создании экз. шаблонного класса
От: Аноним  
Дата: 25.05.04 08:03
Оценка: +1 :)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

RB>>Да, хочу .


L_L>Так Бог в помощь. Напиши свой компилятор, продемонстрируй достоинства твоего расширения и пиши в комитет по расширениям языка.


.

Просто всегда хочется, чтобы компилятор тебя понимал и угадывал все твои желания.
Re[2]: Определение типа при создании экз. шаблонного класса
От: Сергей Зизев Украина  
Дата: 25.05.04 08:23
Оценка:
Здравствуйте, Juny, Вы писали:

J>Здравствуйте, RobinBobin, Вы писали:


RB>>Возник такой вопрос: почему компилятор не может вывести тип при создании экземпляра шаблонного класса так же, как он делает при вызове шаблонной функции?


J>Я тут Страуструпа читал....


J>

J>Обратите внимание, что параметры шаблона класса(в отличие от шаблона функции) никогда не выводятся. Причина заключается в том, что гибкость, обеспечиваемая наличием нескольких конструкторов класса, во многих случаях является непреодолимым препятствием на пути такого выведения, и еще в большем числе случаев выведение неоднозначно.


Также добавлю, что этой теме посвящена глава книги Д.Вандевурда "Шаблоны С++"

13.15 Initializer Deduction

It is often said that "programmers are lazy," and sometimes this refers to our desire to keep programmatic notation compact. Consider, in that respect, the following declaration:

std::map<std::string, std::list<int> >* dict 
= new std::map<std::string, std::list<int> >;


This is verbose, and in practice we would (and most likely should) introduce a typedef synonym for the type. However, there is something redundant in this declaration: We specify the type of dict, but it is also implicit in the type of its initializer. Wouldn't it be considerably more elegant to be able to write an equivalent declaration with only one type specification? For example:

dcl dict = new std::map<std::string, std::list<int> >;


In this last declaration, the type of a variable is deduced from the type of the initializer. A keyword (dcl in the example, but var, let, and even auto have been proposed as alternatives) is needed to make the declaration distinguishable from an ordinary assignment.

So far, this isn't a template-only issue. In fact, it appears such a construct was accepted by a very early version of the Cfront compiler (in 1982, before templates came on the scene). However, it is the verbosity of many template-based types that increases the demand for this feature.

One could also imagine partial deduction in which only the arguments of a template must be deduced:

std::list<> index = create_index(); 
Another variant of this is to deduce the template arguments from the constructor arguments. For example:

template <typename T> 
class Complex { 
  public: 
    Complex(T const& re, T const& im); 
    … 
}; 

Complex<> z(1.0, 3.0);  // deduces T = double


Precise specifications for this kind of deduction are made more complicated by the possibility of overloaded constructors, including constructor templates. Suppose, for example, that our Complex template contains a constructor template in addition to a normal copy constructor:
template <typename T> 
class Complex { 
  public: 
    Complex(Complex<T> const&); 

    template <typename T2> Complex(Complex<T2> const&); 
    … 
}; 

Complex<double> j(0.0, 1.0); 
Complex<> z = j;  // Which constructor was intended?


In the latter initialization, it is probable that the regular copy constructor was intended; hence z should have the same type as j. However, making it an implicit rule to ignore constructor templates may be overly bold.

Re: Определение типа при создании экз. шаблонного класса
От: Кодт Россия  
Дата: 25.05.04 09:29
Оценка: 1 (1)
Здравствуйте, RobinBobin, Вы писали:

RB>Возник такой вопрос: почему компилятор не может вывести тип при создании экземпляра шаблонного класса так же, как он делает при вызове шаблонной функции?


Увы тебе, это (имхо) даже стандартом не предусмотрено.

RB>
RB>template <class TYPE>
RB>struct ARRAY
RB>{
RB>   TYPE     *pArray;
RB>   DWORD    dwSize;

RB>   ARRAY(TYPE *array, DWORD size)
RB>   {
RB>      pArray = array; dwSize = size;
RB>   }
RB>};

RB>BYTE byte_buf[] = {10, 20, 30};
RB>ARRAY arr(byte_buf, 3); // Ошибка!!!
RB>


Если arr — временный объект, то можно использовать производящие функции:
template<class T>
ARRAY<T> makearray(T* buf, int size) // вывели тип и сконструировали объект
{
  return ARRAY<T>(buf,size);
}


ЗЫ.
Нехорошо давать классам ИМЕНА — обычно так обозначают макросы и винапишные типы (последее идёт по традиции, опять-таки от макросов).
Перекуём баги на фичи!
Re[2]: Определение типа при создании экз. шаблонного класса
От: Аноним  
Дата: 25.05.04 09:33
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Если arr — временный объект, то можно использовать производящие функции:


Да, спасибо! Это я не подумал .

К>ЗЫ.

К>Нехорошо давать классам ИМЕНА — обычно так обозначают макросы и винапишные типы (последее идёт по традиции, опять-таки от макросов).

Не, я только структурам даю. Или тоже плохо? Хотя разница между структурой и классом...
Re[2]: Определение типа при создании экз. шаблонного класса
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 25.05.04 09:59
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Если arr — временный объект, то можно использовать производящие функции:

К>
К>template<class T>
К>ARRAY<T> makearray(T* buf, int size) // вывели тип и сконструировали объект
К>{
К>  return ARRAY<T>(buf,size);
К>}
К>


Согласен. А лучше так:
template<class T>
struct array_ref
{
    T *P;
    size_t Size;
    template<size_t Size_>
    array_ref(T (&X)[Size_]): P(X), Size(Size_) {}
};

template<class T, int Size>
array_ref<T> make_array_ref(T (&X)[Size]) { return array_ref<T>(X); }


А если вся заварушка только для begin и end (например для for_each), тогда так можно:
template<class T, int Size>
T *array_begin(T (&X)[Size]) { return X; }

template<class T, int Size>
T *array_end(T (&X)[Size]) { return X+Size; }
[c]

Пример:
[c]
#include <iostream>
#include <algorithm>

void print(int &x) { std::cout << x << std::endl; }

int qw[] = { 6, 7, 90, 87 };

int main(int argc, char *argv[])
{
    array_ref<int> qw_ref(qw); // здесь, к сожалению, нельзя без указания типа.

    make_array_ref(qw); // создает array_ref<int>.

    std::for_each(array_begin(qw), array_end(qw), print); // ...
}
getboost.codeplex.com
citylizard.codeplex.com
Re[3]: Определение типа при создании экз. шаблонного класса
От: Павел Кузнецов  
Дата: 25.05.04 14:27
Оценка:
> К>Нехорошо давать классам ИМЕНА — обычно так обозначают макросы и винапишные типы (последее идёт по традиции, опять-таки от макросов).
>
> Не, я только структурам даю. Или тоже плохо?

Скажем так: чревато. Вот совсем недавний пример: http://rsdn.ru/forum/Message.aspx?mid=646493
Автор: enots
Дата: 19.05.04
Posted via RSDN NNTP Server 1.9 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[4]: Определение типа при создании экз. шаблонного класса
От: Аноним  
Дата: 25.05.04 14:39
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Скажем так: чревато. Вот совсем недавний пример: http://rsdn.ru/forum/Message.aspx?mid=646493
Автор: enots
Дата: 19.05.04


Да, поучительно! Даже не знаю, что сказать. Просто я в своё время решил, что свои структуры буду именовать по подобию АПИшных... Видать, неправильно решил

Robin
Re[3]: Определение типа при создании экз. шаблонного класса
От: LaptevVV Россия  
Дата: 25.05.04 15:24
Оценка:
Здравствуйте, Сергей Зизев, Вы писали:

СЗ>Также добавлю, что этой теме посвящена глава книги Д.Вандевурда "Шаблоны С++"


СЗ>[q]

СЗ>13.15 Initializer Deduction

СЗ>It is often said that "programmers are lazy," and sometimes this refers to our desire to keep programmatic notation compact. Consider, in that respect, the following declaration:


СЗ>[]

На русском писать надо!!!! Книжка давно уже вышла из печати. И даже рецензия на нее леждит на сайте.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[4]: Определение типа при создании экз. шаблонного класса
От: Сергей Зизев Украина  
Дата: 25.05.04 15:28
Оценка:
Hello, LaptevVV!
You wrote on Tue, 25 May 2004 15:24:48 GMT:

[skipped...]

L> На русском писать надо!!!! Книжка давно уже вышла из печати. И даже рецензия на нее леждит на сайте.

У меня нет русского варианта в электронном виде.

WBR
Posted via RSDN NNTP Server 1.7 "Bedlam"
Re[4]: Определение типа при создании экз. шаблонного класса
От: Сергей Зизев Украина  
Дата: 25.05.04 15:31
Оценка:
Hello, LaptevVV!
You wrote on Tue, 25 May 2004 15:24:48 GMT:

[skipped...]

L> На русском писать надо!!!! Книжка давно уже вышла из печати. И даже рецензия на нее леждит на сайте.

У меня нет русского варианта в электронном виде.

WBR
Posted via RSDN NNTP Server 1.7 "Bedlam"
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.