Шаблоны C ++, проблема с объектом, выделенным как «статическим», так и «динамическим» - PullRequest
3 голосов
/ 02 апреля 2011

Что не так в этом коде?

template <typename T>
class Sample
{
public:
    T first;
    T second;
    typedef T Type;
};

and 

template <typename Item> 
class Process
{
public:
    void process (Item *item) 
    {
        typename Item::Type var = item->first + item->second;
        //Some code...
    }
};

Метод "процесс" должен иметь возможность работать с объектом, выделенным как "статический", так и "динамический" ... Первый параметр работает

int main(int argc, _TCHAR* argv[])
{
Sample <double> s;
Process <Sample <double> > a;
a.process(&s);

return 0;
}

, но второйне

int main(int argc, _TCHAR* argv[])
{

Sample <double> *s = new Sample <double>();
Process <Sample <double> *> a;
a.process(s); //Error  C2664: 'Process<Item>::process' : cannot convert parameter 1 from 'Sample<T> *' to 'Sample<T> *'
return 0;
}

Как спроектировать класс и метод «процесс», чтобы можно было работать с объектом, выделенным как «статическим», так и «динамическим»?Спасибо за вашу помощь ...

Ответы [ 4 ]

3 голосов
/ 02 апреля 2011

Process <Item>::process() ожидает Item*, поэтому Process <Sample <double> *>::process() ожидает Sample <double>**.

Однако решение гораздо проще:

Sample <double> *s = new Sample <double>();
Process <Sample <double> > a;
a.process(s);

Для Process,совершенно неважно, как объект был размещен, все, что он получает, - это указатель на него и работает с ним (при условии, что он не будет владеть или пытаться удалить объект).

2 голосов
/ 02 апреля 2011

Проблема не в том, что объект был выделен определенным образом. Невозможно определить, был ли объект размещен в стеке или в свободном хранилище с учетом только одного указателя, по крайней мере, с помощью любого переносного стандартного средства. Доступ к членам объекта с помощью указателя происходит одинаково как для объектов «стека», так и для объектов «свободного хранилища».

Фактическая проблема заключается в том, что вы передаете неправильный тип в определение переменной Process<> во втором фрагменте:

Process <Sample <double> *> a;

Взгляните на определение Process<>:

template <typename Item>
class Process
{
public:
    void process (Item *item)
    { /* ... */ }
};

Если Item имеет тип Sample <double> *, то сигнатура функции для process() становится:

void process (Sample <double>** item)
{ /* ... */ }

По-видимому, это не то, что вы хотите.

Чтобы это исправить, измените

Process <Sample <double> *> a;

до

Process <Sample <double> > a;

В последнем случае сигнатура функции для process() становится void process (Sample <double>* item), что должно позволить компилировать оба ваших фрагмента кода.

2 голосов
/ 02 апреля 2011
Sample <double> *s = new Sample <double>();
Process <Sample <double> *> a; //<<----------- here you go wrong!
a.process(s); 

Аргументом Process по-прежнему должно быть Sample<double>, а не Sample<double>*, поскольку последний делает Item* => Sample<double>**, который вы не передаете при вызове process функции-члена,

Итак, правильный код должен быть таким:

Process <Sample<double> > a; //<<----------- now it's correct!
a.process(s);

Это должно работать сейчас!

Или сделать это:

Sample <double> *s = new Sample <double>();
Process <Sample <double> *> a; //<------ your version!
a.process( &s );                 //<------ note I'm passing pointer to pointer!
       // ^^ note the ampersand (&)
1 голос
/ 02 апреля 2011
Process <Sample <double> *> a;
a.process(s);

Подпись Process.process для приведенного выше кода будет void process(Sample <double> **), поскольку Item равно Sample <double> * - Вы хотите, чтобы оно было void process(Sample <double> *)

Изменить это:

Process <Sample <double> *> a;

Кому:

Process <Sample <double> > a;

Если вы посмотрите полное сообщение об ошибке, вероятно, компилятор расскажет вам о двух различных T, используемых при попытке сопоставить один Sample<T> с другим Sample<T>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...