Reputation: 1822
I have to maintain a program that nobody has touched since 2004.
class CSolver
{
...
ClauseIdx add_clause (int * lits, int n_lits);
}
void and2 (CSolver & solver)
{
vector <int> lits;
...
solver.add_clause(lits.begin(), lits.size());
}
The compiler complains that:
error: no matching function for call to ‘CSolver::add_clause(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, size_t)’
I try to cast it
solver.add_clause((int*)lits.begin(), lits.size());
But there is still a complaint:
error: invalid cast from type ‘__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >’ to type ‘int*’
I want to look for a quick fix on this, because changing interface of CSolver will result changing the whole program.
Thanks in advance.
Upvotes: 4
Views: 3130
Reputation: 3125
Not so fast dear. Of course you can apply the solution already expressed by others:
solver.add_clause(lits.data(), lits.size());
or my preferred choice :
solver.add_clause(&lits[0], lits.size());
which designates that something uncommon goes on here,
but you should first consider that even if the standard defines that vector internal storage should be contiguous , this does not mean it is not reallocatable. Unfortunately the latter happens quite often.
Upvotes: 0
Reputation: 1028
You can just use like this to avoid of casting:
solver.add_clause(&(*lits.begin()), lits.size())
Here, take the *list.begin() and get its address, the address is a int *
Upvotes: 2
Reputation: 16187
This should work on multiple platforms without C++11 support:
solver.add_clause(&lits[0], lits.size());
Edit: The assumptions here being you just want to satisfy the API and you have resized the vector to have enough ints allocated for the operation and that the add_clause method is not going to muck with pointers, allocate new integers, or otherwise violate the heap.
The reason for this workaround being possible is due to the vector's internal contiguous allocation on the heap so a pointer to the first element is sufficient to use the container as an array for c-style iteration of elements as long as you note the amount of elements.
Upvotes: 4
Reputation: 13651
If you can compile against c++11, you can use
solver.add_clause(lits.data(), lits.size());
http://en.cppreference.com/w/cpp/container/vector/data
Upvotes: 7
Reputation: 503775
Like this:
solver.add_clause(lits.data(), lits.size());
Don't add casts without understanding what you're doing.
The function wants an array of int
s, and it's asking for them by a pointer to the first element along with a size. This is a common C convention.
Lucky for us, std::vector
stores elements precisely as a contiguous array, so we can get a pointer to the first element (lits.data()
, &lits[0]
, &lits.front()
, etc.) and then just pass the size.
Upvotes: 11