Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Специализация конструктора с параметром callback, подскажите синтаксис 
V
    Опции темы
null56
Дата 1.2.2010, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



Всем привет
Поясню что хочу сделать: хочу создать такой класс - шаблон, который бы принимал два параметра:
- тип хранимого значения
- функция callback, которую бы он вызывал у себя в деструкторе, другими словами автоматический закрыватель каких - либо хендлов
Пытаюсь определить полную специализацию конструктора класса для типа int, но видимо не правильно определяю ее
Класс
Код

template <typename T, void (*f)(T)>
class Class
{
public:
        //-
        Class<int, void (*f)(int)>() { m_Var = 10; } // проблема тут
        //-
        ~Class() { (*f)(m_Var); }
        T m_Var;
};


Вывод компилятора в отношении строки - проблемы

Цитата

1.h:5: ошибка: `*' не может присутствовать в константном выражении
1.h:5: ошибка: a call to a constructor не может присутствовать в константном выражении
1.h:5: ошибка: a function call не может присутствовать в константном выражении
1.h:5: ошибка: некорректный аргумент шаблона 


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

Заранее благодарен всем откликнувшимся
PM MAIL   Вверх
586
Дата 1.2.2010, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 10
Всего: 146



Код
// шаблонный класс
template <typename T, void(*f)(T)>
class Class
{
    T m_var;
public:
    Class() { m_var = 10; }
    ~Class() { f(m_var); }
};

// частичная специализация
template <void (*f)(int)>
class Class<int, f>
{
    int m_var;
public:
    Class() { m_var = 10; }
    ~Class() { f(m_var); }
};


// полная специализация

void test(int)
{
}

template <>
class Class<int, test>
{
    int m_var;
public:
    Class() { m_var = 10; }
    ~Class() { test(m_var); }
};

int main()
{
}


Это сообщение отредактировал(а) 586 - 1.2.2010, 16:31
PM   Вверх
tolgamrab
Дата 1.2.2010, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 1.2.2010
Где: г. Смоленск

Репутация: нет
Всего: нет



Рассматриваемая задача не нова. Это классически пример паттерна контейнер(ресурс)
Вариант первый - решение задачи в лоб:
Код

template <class TStore>
class TContainer
{
public:
    typedef void (*TCallback)(TStore&);
private:
    TStore _data;
    TCallback _callback;
public:
    TContainer(TStore &data, TCallback callbackFunction) :
        _data(data), _callback(callbackFunction)
    {}
    ~TContainer(void)
    {
        (*_callback)(data);
    }
};


Использование:
Код

void myReleaser(int& handle);
void someFunction(void)
{
    TContainer<int> container(handle, myReleaser);
}


Но лучше все же не баловаться callback процедурами и писать контейнер исходя из того, что он сам заботится  об удалении ресурса, при необходимости специализировать шаблон для своего типа ресурса хитрым деструктором. А еще лучше - воспользоваться написанным. auto_ptr подходит как нельзя лучше для решения этой задачи. Нужно или написать обертку для хэндла - в конструкторе создаем, в деструкторе удаляем и все это дело на вход auto_ptr, или посмотреть на реализации умных указателей из любой приличной библиотеки. Там можно явно задавать и тип хранимого значения и стратегию удаления.

PM MAIL ICQ   Вверх
null56
Дата 1.2.2010, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



586, спасибо, теперь понятнее...
только не могу понять одну фразу из книги про шаблоны
Цитата

... Однако при специализации класса необходимо специализировать все его члены-функции.  Хотя можно специализивать и отдельную функцию-член, после этого нельзя будет специализировать целый класс

что имел в виду автор в контексте второго предложения про отдельную функцию - член?

Добавлено через 2 минуты и 30 секунд
tolgamrab, да, про библиотеку согласен, просто разбираюсь с шаблонами... тебе тоже спасибо за пример
PM MAIL   Вверх
586
Дата 1.2.2010, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 10
Всего: 146



Цитата(null56 @  1.2.2010,  17:13 Найти цитируемый пост)
Цитата
Хотя можно специализивать и отдельную функцию-член, после этого нельзя будет специализировать целый класс

Да. Действительно.
Код
#include <iostream>

template <typename T>
class A
{
public:
    void test();
};

// реализация метода шаблонного класса
template <typename T>
void A<T>::test(void)
{
    std::cout << "A<T>::test()\n";
}

// специализация метода шаблонного класса для int
template <>
void A<int>::test(void)
{
    std::cout << "A<int>::test()\n";
}

// здесь получится объявить полную специализацию шаблонного класса, т.к. нету отдельной специализации методов для типа short
template <>
class A<short>
{
};

// здесь не получается сделать полную специализацию шаблонного класса, т.к. у класса специализированы методы отдельно
/*
template <>
class A<int>
{
};*/

int main()
{
    A<int> a;
    A<char> b;
    a.test();
    b.test();
}


Это сообщение отредактировал(а) 586 - 1.2.2010, 19:11
PM   Вверх
null56
Дата 1.2.2010, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



спасибо, так намного понятнее
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0467 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.