Оцените любой тип или функцию, используя шаблоны - PullRequest
0 голосов
/ 25 марта 2012

Я оставил все предыдущие записи о проблемах с документами, в то время как грузы выяснились, EDIT2 - это текущее состояние:

В настоящее время я работаю над простой системой графического интерфейса для университетской курсовой работы, и у меня возникла простая идея и вопрос. Я думал о каком-то динамическом лейбле:

Вместо того, чтобы передавать значение / строку каждый кадр в «статическую» метку, я подумал, что было бы неплохо, если бы «динамический» класс меток мог просто связывать все виды функций или указателей для их автоматической печати в каждом кадре.

Вот некоторый псевдокод, чтобы продемонстрировать, чего я хочу достичь:

/* OLD WAY */
// called on initialization:
CView* pView = new CView();
CLabel* pLabel = new CLabel(10,20,"TEST");
pView->Attach(pLabel);
GUIManager->SetActive(pView);
// ...
// called every frame somewhere:
pLabel->SetText(AppTime->GetFPS()); //(AppTime is a singelton with time informations)

/* NEW WAY */
// called on initialization:
CView* pView = new CView();
//(the return type of GetFPS is float)
CDynamicLabel<float>* pDLabel = new DynamicLabel<float>(10,20, *AppTime->GetFPS());
// not only functions or member functions, this should also be possible
CDynamicLabel<int>* pDLabel2 = new DynamicLabel<int>(20,20, ptrToSomeInteger);

Так что я думаю, что должен быть способ объединить систему шаблонов C ++ и boost :: bind, чтобы получить эту функциональность, которую я хочу, но я не могу понять, как. Я надеюсь, что кто-то может дать мне несколько советов о том, как этого добиться. Может быть, есть даже другой способ получить эту функцию, которая более распространена.

EDIT: Чтобы прояснить ситуацию, код C ++, связанный с динамической меткой, еще не реализован. Я все еще изо всех сил пытаюсь найти идеальный способ реализовать это, но проясняю некоторые вещи о моей нынешней иерархии классов:

У меня есть виртуальный класс CElement, из которого получается каждый GUIElement. Существуют виртуальные функции для рендеринга, обновления (с переданным временем в качестве аргумента) и функции OnEvent с событием в качестве аргумента. Также общая функция видимости реализована в классе CElement. CView - это класс, который представляет определенную настройку CElements. GUIManager - это Singleton, который перенаправляет все вызовы в текущее представление и связанные элементы.

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

Я надеюсь, что все прояснилось ...

EDIT2: / * удалено, потому что код все равно не работал ... * /

EDIT3: Все заработало, я использовал boost :: function и boost :: bind и написал шаблон, который теперь может делать все, что я хотел ...

Ответы [ 3 ]

1 голос
/ 25 марта 2012

Не могли бы вы немного подробнее рассказать о сценарии использования?

AFAICT, в приведенном вами примере значение будет где-то преобразовано в текст, чтобы его можно было отобразить на экране.Да?

Итак, я могу понять, как передать указатель или ссылку на текст, который будет отображаться в метке.Затем программа «на стороне пользователя» может изменить текст после создания метки.Но это оставляет неопределенным то, как метка знает, что она должна перерисовать текст.Так что это не идеально.

Я также могу понять передачу указателя функции на метку.Функция будет возвращать (указатель на) фрагмент текста, который должен быть визуализирован.Это полезно, потому что эта функция выполняется, чтобы определить, изменилось ли значение, и соответствующим образом преобразовать значение в текст.

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

Это, кажется, единственный существенный случай.Все остальное, кажется, выполнимо, используя это.Таким образом, метка может быть основана на функции, которая скрывает тип, а не тип данных значения, что не имеет значения, так как оно все равно должно быть преобразовано в текст.

Еще одним преимуществом этого является функцияможет убедиться, что формат выглядит правильно.Мне нравятся такие вещи, как время кадра, для рендеринга в виде поля фиксированной ширины, и некрасиво, если оно уменьшается и расширяется.

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

Сводка: шаблон для функции, которая возвращает текстовую строку, или шаблон для класса, который имеет четко определенную функцию, которая возвращаеттекстовая строка.

Редактировать (в результате пиццы) Это может быть полезным способом обдумать это.

Элегантным решением проблем смэ является «интерфейс» (например, Java, Golang или...).

В этом случае интерфейсу требуется только одна функция без параметров, которая возвращает (в моем примере) текстовую строку.Это интерфейс, который передается на этикетку.

Интерфейс должен встраивать значение, ссылку или указатель на объект (экземпляр класса или POD), который реализует значение, и этот класс или POD должен иметь способ дать текстовую строку.

Класс или POD, который реализует значение, скрыт от метки интерфейсом.

0 голосов
/ 26 марта 2012

Для всех, кто хочет сделать что-то подобное, вот мой последний простой тестовый код, который я придумал, который иллюстрирует функциональность:

/* DynamicLabel.hpp */
template <class T> class CDynamicLabel : public CElement
{    
public:
    CDynamicLabel(void) {}
    CDynamicLabel(boost::function0<T> f) : m_f(f) {}
    void TestCall(void) const { cout << m_f(); }
private:
    boost::function0<T> m_f;
};
/* Test Code in Main (MEMFUNC is a Macro to simplify binding and AppTime is a definition to simplify the CAppTime-Singleton calls) */
CDynamicLabel<float> TestDL(MEMFUNC(&CAppTime::GetLastGPUDelta, AppTime));
TestDL.TestCall();
0 голосов
/ 25 марта 2012

Я не знаю вашу иерархию классов, но вот общая идея:

#include <type_traits>

struct CLabel { virtual ~CLabel() { } /* ... */ };

template <typename T>
struct DynamicLabel : CLabel
{
    DynamicLabel(T);
    // ...
};

template <typename T>
CLabel * LabelMaker(T x)
{
    return new DynamicLabel<typename std::remove_reference<T>::type>(x);
}

Теперь вы можете использовать:

CLabel * p = LabelMaker(12U), * q = LabelMaker(1.5L);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...