How to pass vector <int> to int *

I need to support a program that no one 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: there is no corresponding function to call in "CSolver :: add_clause" (__ gnu_cxx :: __ normal_iterator <int *, std :: vector <int, std :: allocator <int> gt ;, size_t)

I'm trying to use it

 solver.add_clause((int*)lits.begin(), lits.size()); 

But there is still a complaint:

error: invalid listing from type '__gnu_cxx :: __ normal_iterator <int *, std :: vector <int, std :: allocator <int →> for input' int *

I want to find a quick fix for this, because the CSolver interface will change the entire program.

Thanks in advance.

+4
source share
5 answers

Like this:

 solver.add_clause(lits.data(), lits.size()); 

Do not add castings without understanding what you are doing.

The function wants an array of int s, and it requests them with a pointer to the first element along with the size. This is a common C convention.

Fortunately for us, std::vector stores the elements exactly like a continuous array, so we can get a pointer to the first element ( lits.data() , &lits[0] , &lits.front() , etc.), and then just pass the size.

+11
source

If you can compile C ++ 11, you can use

 solver.add_clause(lits.data(), lits.size()); 

http://en.cppreference.com/w/cpp/container/vector/data

+7
source

This should work on multiple platforms without C ++ 11 support:

 solver.add_clause(&lits[0], lits.size()); 

Edit: Assumptions that you just want to satisfy the API, and you resized the vector to have enough ints allocated for the operation, and that the add_clause method is not going to guess with pointers, allocate new integers or otherwise break the heap.

The reason for this possible solution is related to the vector internal adjacent distribution on the heap, so the pointer to the first element is enough to use the container as an array to iterate the c-style elements if you notice the number of elements.

+4
source

You can simply use this to avoid casting:

 solver.add_clause(&(*lits.begin()), lits.size()) 

Here, take * list.begin () and get its address, the address is int *

+2
source

Not so expensive soon. Of course, you can apply a solution already expressed by others:

 solver.add_clause(lits.data(), lits.size()); 

or my preferred choice:

 solver.add_clause(&lits[0], lits.size()); 

which means that something unusual is happening here,

but you should first think that even if the standard defines that vectorial internal storage should be contiguous , this does not mean that it is not redistributed . Unfortunately, the latter happens quite often.

0
source

Source: https://habr.com/ru/post/1501731/


All Articles