instantiate pair object in C++ - c++11

I have a vertex class with many objects, e.g.
class Vertex{
int i;
public:
Vertex(const int & a):i(a){}
};
Vertex v1(1),v2(2)...v100(100);
Now I want to make 50 pairs, each pair linking two vertices. What is the best way to achieve this? I definitely don't want to do the following:
std::pair<const Vertex &, const Vertex &> p1(v1,v2);
...
std::pair<const Vertex &, const Vertex &> p50(v99,v100);
std::make_pair seems to be a better choice. But it only accept values, not references, if I understand correctly. Thanks a lot.

std::make_pair can be used to create pairs of references through the use of std::ref. std::ref stores a reference in a std::reference_wrapper, which through template type deduction, reduces back to the reference. For a const reference, use std::cref.
As the other answers suggest, I'd recommend storing your Vertexes in a std::vector, and initialize them in a for loop. Similarly, store your std::pairs of Vertex references in a vector and construct them in a loop as well.
constexpr auto num_vertices = 100;
std::vector<Vertex> v;
v.reserve(num_vertices);
for (auto i = 0; i < num_vertices; ++i)
v.emplace_back(i);
std::vector<std::pair<const Vertex&, const Vertex&>> p;
p.reserve(num_vertices/2);
for (auto i = 0; i < num_vertices; i += 2)
p.emplace_back(v[i], v[i+1]);
Notice that emplace_back is used to construct the Vertexes and std::pairs in-place.
However, if you are tied to 50 lines of pair initialization, and want to use the type deduction offered by std::make_pair, use:
auto p1 = std::make_pair(std::cref(v1), std::cref(v2)),
p2 = std::make_pair(std::cref(v3), std::cref(v4)),
// ...
p50 = std::make_pair(std::cref(v99), std::cref(v100));
But in this case, it's simpler to just use uniform initialization:
std::pair<const Vertex&, const Vertex&> p1 = {v1, v2},
p2 = {v2, v3},
// ...
p50 = {v99, v100};
Here's a live example on ideone.com.

Why not use a std::vector to store your pairs of Vertex's?
std::vector<std::pair<Vertex, Vertex>> v;
v.reserve(50); // Reserve memory to avoid unnecessary allocations.
for (int i = 1; i < 100; i += 2) {
v.emplace_back(i, i + 1); // Create 50 pairs in vector.
}
Later access individual vertices like so:
auto& p1 = v[0];
/* ... */
auto& p50 = v[49];
If you really want to keep 100 variables for all the vertices then you can store constant references to Vertex in std::pair using std::reference_wrapper:
auto p1 = std::make_pair(std::cref(v1), std::cref(v2));

Related

STL algorithm for splitting a vector into multiple smaller ones based on lambda

Let's say I have a vector containing a struct with a member describing its target vector.
struct Foo
{
int target;
static const int A = 0;
static const int B = 1;
static const int C = 2;
};
std::vector<Foo> elements;
std::vector<Foo> As;
std::vector<Foo> Bs;
std::vector<Foo> Cs;
std::vector<Foo> others;
Now I want to move each Foo in one of the four other vectors based on the value of Target.
For example
auto elements = std::vector<Foo>{ {Foo::A}, {Foo::A}, {Foo::B} };
Should result in two elements in As, one in Bs and none in Cs or others. Elements should be empty afterwards.
I could as well do it myself, but I wonder if there is an STL algorithm I could use to do its job.
Standard algorithms usually don't operate on multiple output destinations, so it's hard to come up with a suitable solution here when you want to abstract away the destination containers through output iterators. What might come closest is std::copy_if. This could look like
// Help predicate creation:
auto pred = [](int target){ return [target](const Foo& f){ return f.target == target; }; };
std::copy_if(elements.begin(), elements.end(), std::back_inserter(As), pred(Foo::A));
std::copy_if(elements.begin(), elements.end(), std::back_inserter(Bs), pred(Foo::B));
std::copy_if(elements.begin(), elements.end(), std::back_inserter(Cs), pred(Foo::C));
std::copy_if(elements.begin(), elements.end(), std::back_inserter(others),
[](const Foo& f){ return false; /* TODO */ });
elements.clear();
If copying is more expensive than move-construction, you should pass std::make_move_iterator(elements.begin()) and the same for elements.end() to the algorithm. The issue here is that this doesn't scale. std::copy_if linearly traverses the input range, and the above has to do this four times. One traversal can be obtained e.g. like the following.
auto doTheWork = [&As, &Bs, &Cs, &others](const Foo& foo) {
if (foo.target == Foo::A)
As.push_back(foo);
else if (foo.target == Foo::B)
Bs.push_back(foo);
else if (foo.target == Foo::C)
Cs.push_back(foo);
else
others.push_back(foo);
};
std::for_each(elements.begin(), elements.end(), doTheWork);
In this scenario, we have at least employed a standard algorithm, but shifted the logic into a rather ugly lambda. Note that the above lambda will always copy its arguments, it needs some adjustments to properly work with std::move_iterators.
Sometimes, a good old range based for loop is the most readable solution.

How to construct a 2-dimensional array in ATS?

For instance, I am looking for an example in ATS that does more or less what the following C code does:
int *theMultable[10][10];
void
theMultable_initialize()
{
int i, j;
for (i = 0; i < 10; i++)
{
for (j = 0; j < 10; j++) theMultable[i][j] := i * j;
}
return;
}
One possible approach is to attempt a direct translation to C. However, I now think that I should have used builtin matrix type instead. This code relies on quite a bit of advanced functionality (I even left one unproven lemma for exercise: it shows that N*sizeof(T) == sizeof(#[T][N]).
The loop to initialize a 2-dimensional array is implemented in the function:
extern
fun
multable_init (
mat: &(#[#[int][10]][10])? >> _
): void // end of [multable_init]
This function, in turn, uses two functions (both initialize an array of elements, basically). Also, the global variable multable is allocated, and is then initialized using multable_init (I thought it wouldn't work, but it did!).
Here's the code of initialization of the global variable:
var multable : #[int?][100]
val p_multable = addr#multable
prval pf_multable = array_v_group (view#multable)
val () = multable_init (!p_multable)
prval pf_multable = array_v_ungroup (pf_multable)
prval pf_multable = array2matrix_v (pf_multable)
val theMultable = ref_make_viewptr {matrix (int, 10, 10)} (pf_multable | p_multable)
A mutable array is allocated on stack, then we take its address (line 2), turns its corresponding at-proof from #[int?][100] to #[#[int?][10]][10] (via grouping on line 3), and initialize it. Then, we turn the grouped-array view into a matrix view, and finally, put it into a ref-cell.
The full code is at Glot.io

remove element from boost::numeric::ublas::vector

If I declare a boost::numeric::ublas::vector aaa and later call the method aaa.erase_element(n), I get a vector with the same size, but with the n-element equal to zero.
Do you know how can I completely remove the element in order to get a lower-size vector?
I can't use std::vector unfortunately...
template<class T> void remove(vector<T> &v, uint idx)
{
assert(idx < v.size());
for (uint i = idx; i < v.size() - 1; i++) {
v[i] = v[i + 1];
}
v.resize(v.size() - 1);
}
Note: this works if T is a primitive type (int, double, etc.) or simple struct. If T is a pointer
type, or contains pointers, then you may need to look after destruction of referenced objects. Or perhaps use ptr_vector.

Type conversion on multidimensional map iterator

struggling a bit with getting ahold of map keys. I am wanting this method to modify a vector of edges where the index is the dest node and the value at that index is the weight. The vector "edges" is already initialized large enough to hold the edges. The compiler is complaining that it cannot convert iterator type to int. Anyone have any advice or thoughts on how to handle this conversion if it is even possible? Thanks. This is part of an assignment I am working on implementing Dijkstra's shortest path for a MOOC.
void CompleteGraph::GetNodeEdges(int Node, std::vector<int> &edges){
// Modifies a vector of edges given the source node sorted by edge weight
// Iterate over a map. Grab all edges that have the given start node(map's 1st key)
typedef std::map<int, std::map<int, int> >::iterator iter;
for(iter i = Graph.begin(); i != Graph.end(); i++){
if (i->first == Node){
edges[i->second.begin()] = i->second.end();
}
}
// Sort vector here: will do this next
}
Your problem is obviously on this line:
edges[i->second.begin()] = i->second.end();
The type of the key of edges is int, but i->second.begin() is returning an iterator, because i->second returns a map. I guess you need something like:
edges[i->second.begin()->first] = i->second.end();
Depending on what information from Graph you want to use, as you haven't told us about what the Graph represents.
I suspect you are looking for something like this:
iter i = Graph.find(Node);
if (i != Graph.end()) {
map<int, int>& edges_map = i->second;
for (map<int, int>::iterator m = edges_map.begin();
m != edges_map.end(); ++m) {
if (edges.size() <= m->first) {
edges.resize(m->first + 1);
}
edges[m->first] = m->second;
}
}

Secure usage of Cell_handle in a CGAL Delaunay triangulation after point insertion

I'm planning to write an algorithm that will use CGAL Delaunay triangulation data structure.
Basically I need to insert some point into the triangulation, save reference to some cells, and then make some other insertion.
I'm wondering how can I store reference to cells that are not invalidated after insertion of new points in triangulation?
It's seems to me that Cell_handle is just a pointer to an internal structure, so it's dangerous to store it due to reallocation of internal container. In the other hand I can see no way in Triangulation_3 interface to store an index from a Cell_handle.
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_vertex_base_3<K> Vb;
typedef CGAL::Triangulation_hierarchy_vertex_base_3<Vb> Vbh;
typedef CGAL::Triangulation_data_structure_3<Vbh> Tds;
typedef CGAL::Delaunay_triangulation_3<K,Tds> Dt;
typedef CGAL::Triangulation_hierarchy_3<Dt> Dh;
typedef Dh::Vertex_iterator Vertex_iterator;
typedef Dh::Vertex_handle Vertex_handle;
typedef Dh::Point Point;
int main(){
Dh T;
for(int i = 0; i < 100; ++i)
T.insert(Point(rand()%1000,rand()%1000,rand()%1000));
assert( T.is_valid() );
assert( T.number_of_vertices() == 100 );
assert( T.dimension() == 3 );
typedef Dh::Cell_iterator CellIterator;
std::vector<Dh::Cell_handle> hnd;
CellIterator itEnd = T.finite_cells_end();
for(CellIterator it = T.finite_cells_begin(); it!=itEnd; ++it){
const int dist = std::distance(T.cells_begin(),it);
hnd.push_back(it);
}
const int newP(1000);
for(int i = 0; i < newP; ++i)
T.insert(Point(rand()%1000,rand()%1000,rand()%1000));
int finiteC(0),infiniteC(0);
for(int i = 0; i < hnd.size(); ++i){
const int dist = std::distance(T.cells_begin(),hnd[i]);
if(T.is_infinite(hnd[i]))
++infiniteC;
else
++finiteC;
}
assert( T.is_valid() );
return 0;
}
This code systematically crash but, and this is really strange to me, if I change newP to 10000, this code magically works.
Can someone explain me how to handle this problem?
Since a cell can disappear during insertion of a new point, the handle you have saved
are not guarantee to point on what you expect.
You have a crash because you use the triangulation hierarchy that internally creates and remove cells in the internal container. If you use CGAL::Delaunay_triangulation_3, you will not have the crash.
For your problem, you should store a quadruplet of Vertex_handleS and use the is_cell function (documented here).
Indeed, cells can disappear on insertion. You can also use the find_conflicts() function to find the cells that are going to be deleted by an insertion, so that you can update whatever you maintain related to them.

Resources