Как указать возможные типы данных для функции шаблона - PullRequest
2 голосов
/ 18 июня 2011

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

Как я могу сделать так, чтобы я мог использовать эти функции класса-потомка?Или сделать так, чтобы принимались только потомки drawable?

вот начало моей функции.GetPositionY - это функция рисования.

template<typename T, typename T2>
bool CheckCollision(T* obj1, T2* obj2){
    obj1->GetPositionY;

Ответы [ 4 ]

3 голосов
/ 18 июня 2011
Функция

A CheckCollision() требует, чтобы клиент передал объект, который предоставляет методы GetPosition(). Это то, что вы делаете, когда вызываете obj1->GetPositionX() внутри вашего шаблона. Нет причин заставлять его проходить объект drawable.

2 голосов
/ 18 июня 2011

В отличие от C #, который принимает наименьший общий знаменатель и требует использования условия "где" для решения этой проблемы, C ++ идет по пути не проверки использования типа шаблона до тех пор, пока метод фактически не будет вызван с конкретным типом.Таким образом, компилируются только те типы, которые предоставляют требуемые методы.например,

template<typename T, typename T2>
bool CheckCollision(T* obj1, T2* obj2) {
        obj1->GetPositionY;
}

class A
{
        public:
                int GetPositionY;
                A() { };
};

class B
{
        public:
                B() { };
};

int main(int argc, char* argv[])
{
        A a;
        B b;

        // this compiles just fine
        CheckCollision(&a, &a);
        // this line will not compile, "error: 'class B' has no member named 'GetPositionY'"
        // CheckCollision(&b, &b);

        return 0;
}

Здесь обсуждается это различие с обобщениями C # и C ++ .

2 голосов
/ 18 июня 2011

Используя комбинацию:

boost :: is_base_of из Boost.TypeTraits http://www.boost.org/doc/libs/1_46_1/libs/type_traits/doc/html/boost_typetraits/reference/is_base_of.html

и boost :: enable_if

http://www.boost.org/doc/libs/1_46_1/libs/utility/enable_if.html

template<typename T, typename T2>
typename boost::enable_if< boost::is_base_of< Drawable, T1>, bool>::type 
CheckCollision(T* obj1, T2* obj2)
{
  obj1->GetPositionY(); // ... whatever
}
0 голосов
/ 18 июня 2011

Добавьте структуру признака для вашего класса drawable, которую можно использовать для проверки правильности типов, созданных в шаблоне. Это будет выглядеть примерно так:

//default for any data-type
template<typename T>
struct drawable_type
{
    enum { drawable = 0 };
};

//specialization for a drawable class
template<>
struct drawable_type<drawable>
{
    enum { drawable = 1 };
};

template<typename T, typename T2>
bool CheckCollision(T* obj1, T2* obj2) 
{ 
    if (drawable_type<T>::drawable && drawable_type<T2>::drawable)
    {
        //do something
    }
    else
        return false; 
}

Теперь, если прошедшие типы нельзя отрисовать, ваша функция просто вернет false, в противном случае вы можете продолжить тестирование и посмотреть, не произошло ли столкновение.

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