Link to home
Start Free TrialLog in
Avatar of simi
simi

asked on

templates

Hi I have the following problem
template<class A1, class A2) class A;
template<class B1, class B2) class B;

Class A and B are lists.
I want them to be able to export and recive data from other lists.
The first argument shows what type of is the list working with.
The second argument shows the type of data of the object the export is adresed to.
I have a problem when trying to export to an object of the same type.



A<SomeDataType, A> a;
The compiler give an error message saying that an < and not an > is espected for the A argument. That because the A argument is a template and needs it's own parameters defined. Providing the A argument with it's own arguments perpetuates the problem forever, as the new given A argument will need it's own arguments.
Can you please help ?
Avatar of milenvk
milenvk

There is no point in declareing a class which template parameters contain another template of the same type. At least you will have to pass some arguments to the second template argument like:

A<SomeDataType, A<AnotherDataType1, AnotherDataType1>>a;

That'll work fine with the compiler but I don't think that is what you need. If A is a template list and its data is represented with objects of type A1 and it has the ability to export these objects to other objects of type A2, and if you want to export to objects of the same type A1 then just declare it like:

A<A1, A1> a;

And if you want to export to lists of the same type you have to declare a list with any dummy export type and then supply this type as the second parameter. Here's an example:

typedef A<SomeType, SomeDummyListType> Type1;
typedef A<SomeType, Type1> Type2;
Type2 a;

The drawback is that Type1 is not capable of exporting back to Type2. Another way might be to declare another list type with only one template parameter, which is the type that the list works with, and then supply this type as the second parameter to the export cabable list. Here is an example:

template <class A1> class CNoExportList
{
A1 *node;
Add(A1*);
Delete(A1*);
Find(A1*);
//etc...
// ...
};

template <class A1, class A2> CExportCapableList
{
A1 *node;
Add(A1*);
Delete(A1*);
Find(A1*);
ExportTo(A2*);
//etc...
// ...
};

And then the declarations of the variables:

CExportCapableList<SomeType, CNoExportList<SomeType>> a;

But again the CNoExport is no capable of exporting to any kind of lists.
There is no point in declareing a class which template parameters contain another template of the same type. At least you will have to pass some arguments to the second template argument like:

A<SomeDataType, A<AnotherDataType1, AnotherDataType1>>a;

That'll work fine with the compiler but I don't think that is what you need. If A is a template list and its data is represented with objects of type A1 and it has the ability to export these objects to other objects of type A2, and if you want to export to objects of the same type A1 then just declare it like:

A<A1, A1> a;

And if you want to export to lists of the same type you have to declare a list with any dummy export type and then supply this type as the second parameter. Here's an example:

typedef A<SomeType, SomeDummyListType> Type1;
typedef A<SomeType, Type1> Type2;
Type2 a;

The drawback is that Type1 is not capable of exporting back to Type2. Another way might be to declare another list type with only one template parameter, which is the type that the list works with, and then supply this type as the second parameter to the export cabable list. Here is an example:

template <class A1> class CNoExportList
{
A1 *node;
Add(A1*);
Delete(A1*);
Find(A1*);
//etc...
// ...
};

template <class A1, class A2> CExportCapableList
{
A1 *node;
Add(A1*);
Delete(A1*);
Find(A1*);
ExportTo(A2*);
//etc...
// ...
};

And then the declarations of the variables:

CExportCapableList<SomeType, CNoExportList<SomeType>> a;

But again the CNoExport is no capable of exporting to any kind of lists.
Oops... i posted this agin as a comment :(
Hey, I was thinking on your problem and I have a better solution than the one that I proposed before. The general idea is to separate the functionlaity between two template classes - one for list functionality and another for export between two lists functionality. Here's how it goes:

template <class A1> CMyList
{
//List functionality
};

template <class L1, class L2> CListExporter
{
// Export functionality. An export function might have the following
// prototype
void Export(L1 &listFrom, L2 &listTo);
};

Then you can declare the variables like this:

CList<SomeDataType> listA, listB;
CList<OtherDataType> listC;

// This exporter will be able to transfer data between listA and listB
CListExporter<CList<SomeDataType>, CList<SomeDataType>> exporter1;


// This exporter will be able to transfer data from listA or listB to listC
CListExporter<CList<SomeDataType>, CList<OtherDataType>> exporter2;

exporter1.Export(listA, listB);
exporter1.Export(listB, listA);
exporter2.Export(listA, listC);
Avatar of simi

ASKER

It does not help.
I will trie to explain in more details what am I doing.
template<Class A1> class A; // this is a simple linked list
template<Class B1, class B2> class B;//this is a class containing
 two lists. One is having nodes of the type B1. The other one is
having nodes of the type B2. The B2 noded list has no other role
but reciving lists exported by other objects toward the class A.
Then class B has the functions that can update let's say the
B1 objected list according to what is in the B2(the recived list). The functionality can be multiple. One example is that
list of B1 type nodes is updated according to what is in the B2 list(ex: B1 and B2 are identical type of data : a string and an int. When B1 finds a B2 node that has a string that is not in the
list it adds it to the list, and when there is allready in the B!
list a node with the same value in the string field the int field
is upgraded by adding the B2 node int field to the B1 node int field, or ex: B1 and B2 are not identical type of data, but they are both lists and the node has a string as member. The string member is a must. This way the exporter, wich is a list of type C1 let's say, sends its string field containt to the B2 list, by copying the value of the string in the A1(this is defined in class A as export) nodes to the B2 nodes. After this when a node is added to the B class, this time through
another mechanism and not through export import, I want B class to be able to verifi if the provided values for the node have as string field a value that is in the B2 list- the one holding the exported list from C-. )
This way the B class can : export, but at the same time can make verifications and updatings or other operations .
I could have the transfered list outside all classes and being accesed by them. But this way this buffer would be vulnerable because it is accesible to all functions in the probram. What I want to achieve is an entiti, like class B that can import in a self owned buffer and do the operations internally. This way the transfers are done between classes and the incapsulation is strong. The only problem arises, as I have said, when I want to export from a B class to a similar class as B.
The problem is that when I declare the variable of B type I have to provide two arguments. One is the type of data that is in B1, the main list of B, the other one is the one that I intend to export to from B wich is also a B type. Your solution with dummy parameter does not work .

Look

template <class B1, class B2> class B;
B<SomeDataType, B> b;

Here the compiler says that the second argument B is a template and has no arguments.

Your solution
B<SomeDataType, B<SomeDataType, SomeDummyDataType>> b;

does not work because I need a real B as a second argument. Is the one that recives the export.

Lets summerize:
B<T1, T2> is a class that updates an internal list of type T2 to a internal list of type T1.

Of course T1 and T2 must have members to update eachother.

But then you say you want something like
B<T1, B> ????? I don't understand what you want?

B has an interal list of T1 wich is updated with a list of B wich is an internal list of T1 wich is updated with a list of B wich is an internal list of T1 wich is updated with a list of B wich is an internal list of T1 wich is updated with a list of B.... etc...

Ofcourse this never works, it's a recursion nightmare. Even if the compiler accepted your declaration, wich of course he doesn't. It would create an infinitife amount of code.

So the question to you is, what the heck are you trying to do... please define exactly what you mean by T1 is updated by B. I understand your need for an updater (B), and the solution is ok if it has two distinctive datatypes, but I don't understand why the updater must accept itself in the template parameterlist.

I can understand if it was something like this:

typedef B<T11, T12> B_T11_T12;        // a updater for T11 <- T12

B<T2, B_T11_T12>                            
// a updater for T12 wich automatically update T11<- T12 and then T2 <- (T11 <- T12)

But I can't see no need for
B<T, B> ?????
I do not understand what it should do, it looks like nonsense to me... Do you want a update concatenator?... that is possible, as I shown above, but this??????

Please give a good analysis of what you're trying to do, in words, not code, with B<T, B>, what do you want to happen then?

Luc
Avatar of simi

ASKER

Well I will trie to explain again. First of all I am learning, so I might be reiventing the weel and I might start with a model that is square instead of round but I guess that's the way.

I write a program that plays the role of a timesheet. A timesheet like the one every employee has to fill in dayly.
It has to mention what projects the person worked on every day of the week, for each project there are regular hours and overtime yours. A list of projects will hold all valid project codes, so the person filling in the timesheet could not assign a wrong code by mistake.
I wrote the program in C and now I am writting it in C++.

I imagined it in C++ as follows:
I declared an array of seven pointers each of them pointing towards the same type of data, one for every week day.
The type of data those pointers are pointing to is a dynamic allocated simple linked list of a type of data that is a structure containing a string and two floats( the project code, regular hours, and overtime hours).
The list itself knows how to add a new element to the list( it puts it in order and if the project code has allready been assigned to that day it updates the hours etc), how to delete the whole day etc.
Another pointer towards the same type of list is declared to hold the total of the projects. This one adds one or updates it every tyme such a project is added to one of the days of the week.
It keeps a total of how many projects and how many hours for each for the whole week.
Practically I use the same type of data. The problem is that they have to comunicate, the project list has to get information from the day lists.  I could have a list declared outside and the day one exporting to it , then the projects one reading from it. I thought that still this buffer is accesable to the whole program functions so I thought of adding another list to the same class that I used for days and project. This way day can export directly to project. The second list from the class  will have just the role of reciving what is exported from another list. Then the other list from the class will deal internally with the one that is the reciving buffer. No access from outside.
It works.
Ok but, getting back to the list of projects, the one that assures that no project name that is unapropriate will not be used as a field of the nodes in the day and project list.
For this one I do not need but a simple list. No second list. No structure lnode but a simple string, the project code. So I decided that this will be actually a base class for the day and project type of class that I derived from it.
I also decided that both the list class and the double list class, should be templates. This way they could be used in the future for different type of data ( If there will be any use hi hi hi , still I have learned about templates).

As a template I had to deal with two parameters. One of them is representing the type of data the list is storing. The other one is the type of data the list exports to. They can not be the same. By ex. when the project list , that is a simple linked list class  is exporting toward a day which is the double listed class, the type of data the list is holding is a string, and the type of data it exports to is that funny class with two lists. Well the problem arrises when a class
template <class B1, classB2> class B that is the double listed class, exports to one of the same kind. ( I use the same class for the project counting so the class representing monday has to export to the projects in order to keep them updated).
The sintax is  B<the_type_of_data_it_holds, the_type_of_data_it_exports_to> b;
well the_type_of_data_it_exports_to is B.
so B<SomeData, B<<SomeData>, B<<<SomeData>....>>>> the ugly thing
Well since I asked the question I found two other ways of achieving the same result without having to do this, still this kind of situation could occur sometimes.
I appologise for the long story but that was the only way I could make an attempt of making it understandable. I hope it is more clear now.
ASKER CERTIFIED SOLUTION
Avatar of newexpert
newexpert

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial