Question

What is an appropriate type for type T below? I don't want to use auto because I want to create a class with a member variable of type T. Thanks.

int* ptr;
vector<int> vec;

T var = ptr;
T var2 = vec.begin();
T var3 = vec.end();

var++; var2++;         // T should be so that these are legal
T newvar = var2 + 5;   // Allow random access etc.

Based on a comment, here's what I want to do. I want to create a class to represent a graph in adjacency list form but abstract out the low-level underlying implementation detail.

// First implementation
vector<vector<int> > adj1; // adj1[i] gives vector of neighbors of i-th vertex
vector<int> nbrs_of_vertex_0 = {1,2};
vector<int> nbrs_of_vertex_1 = {2,0};
vector<int> nbrs_of_vertex_2 = {0,1};
adj1.push_back(nbrs_of_vertex_0);
adj1.push_back(nbrs_of_vertex_1);
adj1.push_back(nbrs_of_vertex_2);
int degree[3] = {2, 2, 2};

// Second implementation
int all_lists[6] = {1,2, 2,0, 0, 1};
int * adj2[3] = {all_lists, all_lists+2, all_lists+4};


// Common algorithm using both implementation
IteratorType it1 = adj[0].begin();
for(int i = 0; i < degree[0]; i++)
  cout << *it1++;
IteratorType it2 = adj2[0];
for(int i = 0; i < degree[0]; i++)
  cout << *it2++;

The question is: what should be type of IteratorType in above code?

Was it helpful?

Solution

Since c++11 you can use begin and end free function. Both of them work on both standard containers and "c arrays". And since we also have auto in c++11 you can rewrite your code as follows:

// Common algorithm using both implementation
auto it1 = std::begin(adj[0]);
for(int i = 0; i < degree[0]; i++)
  cout << *it1++;
auto it2 = std::begin(adj2[0]);
for(int i = 0; i < degree[0]; i++)
  cout << *it2++;

OTHER TIPS

If I'm understanding your question right (and I'm not sure I am), then if you decide to use int[] internally, you can do

typedef int *Iterator;

and if you decide to use vector<int> internally you can do

typedef vector<int>::iterator Iterator;

and then use Iterator for all your algorithms and either typedef will work (since *Iterator will always be of type int), no rewriting required.

If instead you're worried about what people will pass in to your functions (they might pass in int * and they might pass in vector<int>::iterator), you make a templated function, and again as long as putting a * in front of what they pass in gives an int the function will work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top