4

我必须维护一个自 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());  
}

编译器抱怨说:

错误:没有匹配函数调用 'CSolver::add_clause(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, size_t)'</p>

我尝试投射它

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

但是还是有抱怨:

错误:从类型 '__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >' 到类型 'int*' 的无效转换

我想快速解决这个问题,因为更改 CSolver 的界面会导致整个程序发生变化。

提前致谢。

4

5 回答 5

11

像这样:

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

不要在不了解您在做什么的情况下添加演员表。

该函数需要一个 s 数组int,它通过指向第一个元素的指针和大小来请求它们。这是一个常见的 C 约定。

对我们来说幸运的是,std::vector将元素精确地存储为一个连续的数组,因此我们可以获得指向第一个元素(lits.data()&lits[0]&lits.front()等)的指针,然后只传递大小。

于 2013-09-11T20:31:03.907 回答
7

如果您可以针对 c++11 进行编译,则可以使用

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

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

于 2013-09-11T20:32:18.193 回答
4

这应该可以在没有 C++11 支持的多个平台上工作:

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

编辑:这里的假设是您只想满足 API 并且您已经调整了向量的大小以便为操作分配足够的整数,并且 add_clause 方法不会使用指针、分配新整数或以其他方式违反堆。

这种解决方法可行的原因是由于向量在堆上的内部连续分配,因此只要您注意元素的数量,指向第一个元素的指针就足以将容器用作元素的 c 样式迭代的数组.

于 2013-09-11T20:43:00.433 回答
2

您可以像这样使用来避免强制转换:

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

在这里,取 *list.begin() 并获取它的地址,地址是一个 int *

于 2013-09-11T20:52:25.770 回答
0

没那么快亲爱的。当然,您可以应用其他人已经表达的解决方案:

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

或我的首选:

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

这表明这里发生了一些不寻常的事情,

但是您应该首先考虑即使标准定义 向量内部存储应该是连续的,这并不意味着它不可重新分配。不幸的是,后者经常发生。

于 2015-12-03T15:04:53.350 回答