универсальный абстрактный тип c ++ - PullRequest
0 голосов
/ 24 января 2012

Я хочу определить универсальный класс в c ++, который позволяет выполнять мой алгоритм для любых данных.Проблема в том, что эти данные могут быть любыми (например, вектор с плавающей точкой, график и т. Д.).Можно ли сказать в моем классе, что манипулируемые данные имеют тип T, который может быть чем угодно?Тогда пользователь моего класса должен будет реализовать некоторые методы моего класса относительно манипулирования своими данными (например, в зависимости от своих данных он определяет, как сделать сумму двух данных и т. Д.)

Редактировать:

Как можно создать экземпляр шаблона класса и вызвать его метод?У меня возникает ошибка, когда я делаю:

MyClass<int, int> tst();
tst.test(3, 4); // or even with tst.test<int, int>(3, 4);

Ошибка: запрос на член 'test' в 'tst', который имеет тип не-класса 'MyClass ()'

Классесли определено как:

#include <iostream>
#include <boost/graph/adjacency_list.hpp>

using namespace std;
using namespace boost;

template<typename T1, typename T2>
class MyClass
{
    public:
        MyClass();
        virtual ~MyClass();
        void test(T1 p, T2 s);

    protected:
        struct NodeData
        {
            T1 var1;
            T2 var2;
            int var3;
        };

        struct EdgeData
        {
            int var;
        };

        typedef adjacency_list<setS, setS, undirectedS, NodeData, EdgeData> Graph;
        typedef typename Graph::vertex_descriptor NodeDataID;
        typedef typename Graph::edge_descriptor EdgeDataID;
        typedef typename graph_traits<Graph>::vertex_iterator VertexIterator;

        Graph g;
};

template<typename T1, typename T2>
void MyClass<T1, T2>::test(T1 arg1, T2 arg2)
{
    NodeDataID nId = add_vertex(g);
    g[nId].anything = "but anything is not in struct NodeData !";
    g[nId].var1 = arg1;
    g[nId].var2 = arg2;
    g[nId].var3 = 55;
}

template<typename T1, typename T2>
MyClass<T1, T2>::MyClass()
{
    // ...
}

template<typename T1, typename T2>
MyClass<T1, T2>::~MyClass()
{
    // ...
}

Ответы [ 4 ]

2 голосов
/ 24 января 2012

Как комментирует @Als, вы прекрасно описываете шаблон класса .

. Вы можете получить хорошее представление о предмете в http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fclass_templates.htm

2 голосов
/ 24 января 2012

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

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

1 голос
/ 24 января 2012

При условии, что <T> должен оставаться постоянным:

Я бы порекомендовал иметь класс, который принимает "обработчик операций".Переданный обработчик операций будет обрабатывать все специфичные для типа операции.Это НЕВЕРОЯТНО грубый пример, и я даже не уверен, насколько он функционален, поскольку я некоторое время не реализовывал это и пишу на С ++ без компилятора исключительно из памяти.Тем не менее, это должно показать основную идею.

class CGenericOperationHandler<T>{

   public:
   Sum(<T> left,<T> right);

   Subtract(<T> left,<T> right);

   Multiply(<T> left,<T> right);

}

class CFloatOperationHandler : CGenericOperationHandler<float>{

   public:
   Sum(float left,float right){ return left + right; }

   Subtract(float left,float right){ return left - right; }

   Multiply(float left,float right){ return left * right; }

}


class CAlgoRunner<T>{

    CGenericOperationHandler<T>* myOpHandler;

    CAlgoRunner(CGenericOperationHandler<T>* opHandler){
        myOpHandler = opHandler;
    }

    public:
    <T> RunAlgo(<T> left, <T> right){
        return myOpHandler.Multiply(left, right);
    }

}


main(){
    CFloatOperationHandler theOpHandler;

    CAlgoRunner<float>* myRunner = new CAlgoRunner<float>( theOpHandler );

    float result = myRunner.RunAlgo( 6.0f, 1.5f); //result is (6 * 1.5) i.e. 9
}
0 голосов
/ 12 августа 2013

Это работает, только если вы пишете в одном файле (например, .cpp).Если вы работаете над большими проектами с несколькими файлами (заголовок и источник), вам следует избегать шаблонов, потому что компилятор может видеть и анализировать шаблоны при их использовании.Это огромная проблема, потому что переопределение шаблона часто является ошибкой.

...