LINUX.ORG.RU

Re: (С++) Параметризация типов.

> Как создать функцию-шаблон, принимающую в качестве параметра не переменную, а тип переменной

AFAIK, это невозможно. А как звучит настоящий вопрос?

tailgunner ★★★★★ ()

Re: (С++) Параметризация типов.

Либо так

template < typename T >
void func()
{
 ...
}

и вызывай
func < T > ()

либо можно извратиться так

template < typename T >
void func1(T * )
{
 ...
}

#define func(T) func1((T*)0)

вызвать так
func(double)

Reset ★★★★★ ()

Re: (С++) Параметризация типов.

На самом деле мне нужно было переопределить оператор new, и кажется вот это работает:

void* operator new(size_t s)
{
return malloc(s);
}

Вообще хотелось бы иметь возможность писать нечто вроде

template<class T>
T* construct(T)
{
return new T;
}
Но видимо не судьба.

anonymous ()

Re: (С++) Параметризация типов.

There is no guarantee that new would internally use malloc, or that delete would internally use free.

anonymous ()
Ответ на: Re: (С++) Параметризация типов. от anonymous

Re: (С++) Параметризация типов.

> На самом деле мне нужно было переопределить оператор new, и кажется вот это работает

Ну вообще говоря, так и нужно делать. Таким образом переопределяется глобально оператор new, выделяющий память (но не создающий экземпляры классов).

> Вообще хотелось бы иметь возможность писать нечто вроде

А в чём смысл данной операции? Это же эквивалентно вызову дефолтного "new T".

slav ★★ ()
Ответ на: Re: (С++) Параметризация типов. от slav

Re: (С++) Параметризация типов.

>А в чём смысл данной операции? Это же эквивалентно вызову дефолтного "new T".

Нужно следить за использованием динамической памяти, главным образом для отлова утечек. При использовании голого malloc как я понял возникает проблема с виртуальными функциями, но надеюсь она мне не помешает.

anonymous ()
Ответ на: Re: (С++) Параметризация типов. от anonymous

Re: (С++) Параметризация типов.

Предыдущий ответ относился к переопределенному new, параметризация типа здесь как бы не причем :s

anonymous ()
Ответ на: Re: (С++) Параметризация типов. от anonymous

Re: (С++) Параметризация типов.

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

template<class T>
T* allocate_and_construct(T*)
{
 void* p = malloc( sizeof( T ) );
 return new( p )T();
}

template<class T>
void destruct_and_deallocate(T* t)
{
 t->~T();
 free( t );
}

и дальше можно делать вот так:

A* p; 
A* a = allocate_and_construct( p );
destruct_and_deallocate( a );

devinull ★★ ()

Re: (С++) Параметризация типов.

Автору топика хочется пожелать не заниматься велосипедостроением и использовать проверенные решения - http://valgrind.org/

aton ()
Ответ на: Re: (С++) Параметризация типов. от anonymous

Re: (С++) Параметризация типов.

> При использовании голого malloc как я понял возникает проблема с виртуальными функциями

malloc используется для выделения памяти, заполнение vtable происходит в момент конструирования объекта

aton ()
Ответ на: Re: (С++) Параметризация типов. от aton

Re: (С++) Параметризация типов.

>В конструкторе может кинуться исключение, память никто не вернет.

О ужас! Кошмар! Придется использовать try, catch и throw. Это совсем невозможно пережить?

devinull ★★ ()
Ответ на: Re: (С++) Параметризация типов. от devinull

Re: (С++) Параметризация типов.

> О ужас! Кошмар! Придется использовать try, catch и throw

Твоя ирония здесь не уместна, приведенный тобой код потенциально опасен.

> Это совсем невозможно пережить?

Нет. Сразу об стену.

aton ()
Ответ на: Re: (С++) Параметризация типов. от aton

Re: (С++) Параметризация типов.

>malloc используется для выделения памяти, заполнение vtable происходит в момент конструирования объекта

На счет malloc тоже возникает большой вопрос. При использовании new конструирование объекта происходит автоматически после выделения памяти для его хранения. Но при использовании моей версии new (только malloc) конструктор все равно вызывается. Например, следующий код:

#include <iostream>

using namespace std;

class Cmplx
{
private:
double im;
double re;
public:
Cmplx(double im=3,double re=4)
{
cout<<"Cmplx Constructor\n";
this->im=im;
this->re=re;
}
double getIm() const {return im;}
double getRe() const {return re;}
};

void* operator new(size_t s)
{
cout<<"New: allocating "<<s<<" bytes\n";
return malloc(s);
}

int main(int argc,char **argv)
{
Cmplx *c=new Cmplx;
cout<<c->getIm()<<endl<<c->getRe()<<endl;
return 0;
}

выводит:

New: allocating 16 bytes
Cmplx Constructor
3
4

Проверено в gcc и Visual C++. Вопрос: кто вызывает конструктор в этом случае?

anonymous ()
Ответ на: Re: (С++) Параметризация типов. от anonymous

Re: (С++) Параметризация типов.

Дубль два:
#include <iostream>

using namespace std;

class Cmplx
{
   private:
      double im;
      double re;
   public:
      Cmplx(double im=3,double re=4)
      {
         cout<<"Cmplx Constructor\n";
         this->im=im;
         this->re=re;
     }
    double getIm() const {return im;}
    double getRe() const {return re;}
};

void* operator new(size_t s)
{
   cout<<"New: allocating "<<s<<" bytes\n";
   return malloc(s);
}

int main(int argc,char **argv)
{
    Cmplx *c=new Cmplx;
    cout<<c->getIm()<<endl<<c->getRe()<<endl;
    return 0;
}

выводит:

New: allocating 16 bytes
Cmplx Constructor
3
4 

anonymous ()
Ответ на: Re: (С++) Параметризация типов. от anonymous

Re: (С++) Параметризация типов.

А с чего ты решил, что в данном случае конструктор никто не должен вызывать?

anonymous ()
Ответ на: Re: (С++) Параметризация типов. от anonymous

Re: (С++) Параметризация типов.

new это оператор, который вызывает функцию operator new для выделения памяти под объект, затем вызывает конструктор. Переопределить можно только функцию operator new. Оператор new переопределить невозможно, так как это оператор а не функция. Вот такой вот каламбур :)

aton ()
Ответ на: Re: (С++) Параметризация типов. от aton

Re: (С++) Параметризация типов.

>new это оператор, который вызывает функцию operator new для выделения памяти под объект, затем вызывает конструктор.

Где это написано?

anonymous ()
Ответ на: Re: (С++) Параметризация типов. от eXOR

Re: (С++) Параметризация типов.

> Лушче посмотри на auto_ptr из STL и разные ptr'ы из boost

+1

ИМХО, отслеживанием выделения/освобождения памяти должен заниматься компилятор/библиотека, а не программист.

slav ★★ ()
Ответ на: Re: (С++) Параметризация типов. от aton

Re: (С++) Параметризация типов.

Я вот к этому сказал. В тему-таки или нет?

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

eXOR ★★★★★ ()
Ответ на: Re: (С++) Параметризация типов. от aton

Re: (С++) Параметризация типов.

Как я понял - товарищ хочет изобрести механизм управления памятью через реализацию какого-то своего мегашаблона. Если у тебя есть другое понимание - поделись пожалуйста.

eXOR ★★★★★ ()
Ответ на: Re: (С++) Параметризация типов. от eXOR

Re: (С++) Параметризация типов.

>Как я понял - товарищ хочет изобрести механизм управления памятью через реализацию какого-то своего мегашаблона. Если у тебя есть другое понимание - поделись пожалуйста.

На самом деле мне нужно уметь находить утечки. В перспективе, возможно понадобится ручное управление кучей (если не будет устраивать производительность), если это возможно, но пока что ограничусь стандартными средствами C++.

>common lisp - всему голова :)

Lisp нетехнологичен.

anonymous ()
Ответ на: Re: (С++) Параметризация типов. от anonymous

Re: (С++) Параметризация типов.

Если утечки нужно находить при написании - то пользуйся чем и все - valgrind. Хороший инструмент. Если нужно во время работы.. ты планируешь их много оставлять для runtime'а? Может быть лучше тогда взять язык с gc?

eXOR ★★★★★ ()
Ответ на: Re: (С++) Параметризация типов. от tailgunner

Re: (С++) Параметризация типов.

>>> Лушче посмотри на auto_ptr из STL и разные ptr'ы из boost
>> Лучше посмотреть на Boehm's GC.
> Он умеет вызывать деструкторы? O_O

да, но не всегда :) посмотри /usr/include/gc/gc_cpp.h:
A collectable object may have a clean-up function, which will be
invoked when the collector discovers the object to be inaccessible.
An object derived from "gc_cleanup" or containing a member derived
from "gc_cleanup" has a default clean-up function that invokes the
object's destructors. Explicit clean-up functions may be specified as
an additional placement argument:

A* a = ::new (GC, MyCleanup) A;

Eshkin_kot ★★ ()
Ответ на: Re: (С++) Параметризация типов. от anonymous

Re: (С++) Параметризация типов.

>На самом деле мне нужно уметь находить утечки. В перспективе, >возможно понадобится ручное управление кучей (если не будет >устраивать производительность), если это возможно, но пока что >ограничусь стандартными средствами C++.

1)(один) У меня была аналогичная проблема (VC++). Советую дописать дефолтный макрос DEBUG_NEW, если ты в вижуалсях. Я так и сделал(деталей, извини, не помню). На других компиляторах и идЭешниках , кстати, скорее всего есть аналогичные инструменты. Если в твоём нема, см. вижуалсишный DEBUG_NEW и делай свой по образу и подобию.

2)(два) Может и не в тему, конечно, но... Не советую переопределять new создающий, который для объектов класса, ИМХО жуткий гемор. Почитай теорию (Страуструп, Мейерс и т.д.). там сказано, что для энтого гемора, следует переопределить целый КОМПЛЕКС: new канонический throw std::bad_alloc, new размещающий, new nothrow и delete. Вроде так. Причём если перегрузил один из вышеуказанных, будь добёр и остальные иначе быть попе.

3)(три) Советую также, подумать, а насколько опасна тебе эта самая утечка. Например, в виндах, KDE, других user-time ситемах очень часто на утечку памяти моно забить, т.к. там на 2-ом уровне ядра живёт бог (или баг) по имени "МЕнеджер памяти", который с удовольствием разгребёт твой мусор. Это ещё вопрос, что считать утечкой.

4)(чтыре) Если же ты действительно провёл все необходимые тесты своих структур данных и они однозначно указывают на необходимость динамического освобождения динамически выделенной памяти, подумай об использовании патерна boost::shared_ptr( вроде я видел такой свет в этом топике? ). Если boost::shared_ptr реально снижает эффекимвность, рассмотри Loki::smart_ptr

5)(пять) "Перспектива ручного управления кучей" - это ... ЭЭЭЭ ... ну очень говёная перспектива. Хуже перспективы не придумаешь. Советую крепко подумать, как этого избежать. Дело в том, что я имею грёбаный опыт создания ручных MemoryPool-ов для "no-systemd"-контроллеров на базе C51 и AVR-Risc. Это были приложения для различных "переходников" типа южного/северного мостов в маме-плате. Так вот, там НУЖНО было создавать объекты динамически, но НИКАКИЕ языковые средства для этого не подходили по вполне понятным причинам. Ни тебе маллок, ни нью. Ты прсто не представляешь, сколько граблей было перелопачено.. Вывод: НЕ СТОИТ УПРАВЛЯТЬ КУЧЕЙ ВРУЧНУЮ.

anonymous ()
Ответ на: Re: (С++) Параметризация типов. от Eshkin_kot

Re: (С++) Параметризация типов.

И ещё вот что. В библиотеке Loki есть феноменально-замечательный, платформенно-независимый, полностью соответсвующий стандарту c++, менеджер памяти для малых объектов. Использую эту прелесть в соих прогах - эффективность сильно улучшится.

binf ()
Ответ на: Re: (С++) Параметризация типов. от eXOR

Re: (С++) Параметризация типов.

>Лушче посмотри на auto_ptr из STL и разные ptr'ы из boost

Вощета std::auto_ptr функционально ограниченн своей семантикой разрушающего копирования. Например, его нельзя в контейнерах хранить.

boost::shred_ptr<T> - это хорошо, пока тебя

1.не волнует эффективность работы с кучей

2.ты не планируешь юзать объекты класса Т в многопоточных приложениях.

Насколько я понял, 1) - актуально для автора топика. В будущем возможно понадобится и 2). Чтобы раз и навсегда решить эти проблемы, рискну посоветовать подумать о применеии Loki::SmartPtr. Там, как я уже говорил, есть Small Oject Fixed Allocator, а обёекты класса T, скорее всего имеют малый размер.

binf ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.