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());

何をしているのかを理解せずにキャストを追加しないでください。

この関数はints の配列を必要としており、サイズとともに最初の要素へのポインターによってそれらを求めています。これは一般的な 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 を満足させたいだけであり、ベクトルのサイズを変更して操作に十分な int を割り当て、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 に答える