Self aware objects in templates

Hi,

I am trying to create a powerset template which permits both the input set (in the mathematical sense except that duplicate members are permitted) and output set of sets to be any container.

To do this efficiently it seems necessary to know what sort of containers we are dealing with. Can we do that? How might we best do that?

Here is what I have written. It should be pointed out that I do not know if the rest of the template is correct (some is my best guess at what will work), since this problem has stumped me before I started testing, but it should suffice to give an idea. The problem is explained in the comments in terms of whether the containers are sets or vectors, but I would like a general solution for any container (including custom ones, at least if they meet fairly simple specifications).

All help appreciated!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//Data_ContB must = Some_Container_Type<Data_ContA>
template <class Data_ContA,class Data_ContB>
Data_ContB Powerset(Data_ContA In,Data_ContB& Out)
{	
	if (In.size()==0)
	{
		Data_ContA empty;
		powA.push_back(empty);
	}
	else
	{
		Data_ContA::reverse_iterator i=In.rbegin();
		typename allocator<Data_ContA> taken=*i;
		In.erase(In.rbegin);
		Data_ContB powA;
		Powerset<Data_ContA,Data_ContB>(In,powA);
		Data_ContB powB;
		Data_ContB::iterator l!=powA.end()
		for (Data_ContB::iterator i=powA.begin();i!=l;++i)
		{
			Data_ContA next=*i;
/* Oh no...
		if next is vector:	next.push_back(taken);
		if next is set:	        next.insert(taken);
		if powB is vector:	powB.push_back(next);
		if powB is set:	        powB.insert(next);
*/
		}
/* And again...
	if powA is vector:	powA.insert(powA.end(),powB.begin(),powB.end());
        if powA is set:         powA.insert(powB.begin(),powB.end());
*/
	}
	return powA;
}
Last edited on
With regard to the vector/set choice thing - My suggestion is a couple of overloaded functions.
This example shows what I'm thinking:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//Data_ContB must = Some_Container_Type<Data_ContA>
template <class Data_ContA,class Data_ContB>
Data_ContB Powerset(Data_ContA In,Data_ContB& Out)
{	

	
    //use an overloaded function  to determine whether - Data_ContB 
    //is a list or vector 
    
    int val =1; //Some value
    
    typename Data_ContB::iterator i;
    for (i = Out.begin(); i != Out.end(); ++i)
    {
        PutIntoContainer( *i, val);
    }
    

    return Out;//Just to keep compiler happy.
}


//A couple of overloaded functions
template <typename DataType>
void PutIntoContainer( set<DataType>& cont, DataType & d)
{

    cont.insert(d);
}

template <typename DataType>
void PutIntoContainer( vector<DataType>& cont, DataType & d)
{

    cont.push_back(d);
}

//*********************************************
int main()
{         
         
    set<int > si;
    vector <int>vi;

    si.insert(1);
    si.insert(2);
    si.insert(3);

    vi.push_back(2);
    vi.push_back(3);
    vi.push_back(4);


    vector <set<int> > vsi;
    vsi.push_back(si);
    
    list <vector<int> > lvi;
    lvi.insert(lvi.begin(),vi);

    Powerset(si, vsi);
    Powerset(vi, lvi);

}


An interface consisting of iterators is more flexible than an interface taking containers. Consider, for example, std::copy().
It takes a pair of input iterators that define the range of elements to copy and a third output iterator to where to copy.
This solves your insert/push_back problem.
Topic archived. No new replies allowed.