无法用std::vector初始化Gecode的IntSet,求问题排查
Gecode IntSet初始化编译错误问题解析
问题背景
根据Gecode官方文档《Modelling and Programming with Gecode》及API参考,IntVar可通过IntSet创建,且IntSet支持基于整数集合的初始化。但编写如下代码时出现编译错误:
std::vector<int> values = {2, 4, 6, 8}; IntVar i; Class() : i(*this, IntSet(values)) { }
编译错误信息
In file included from $GECODE_HOME/include/gecode/int.hh:356, from bla.cc:3: $GECODE_HOME/include/gecode/int/int-set-1.hpp: In instantiation of ‘static void Gecode::IntSetInit<I>::init(Gecode::IntSet&, I&) [with I = std::vector<int>]’: $GECODE_HOME/include/gecode/int/int-set-1.hpp:87:24: required from ‘Gecode::IntSet::IntSet(I&) [with I = std::vector<int>]’ bla.cc:14:35: required from here $GECODE_HOME/include/gecode/int/int-set-1.hpp:61:15: error: no match for call to ‘(std::vector<int>) ()’ 61 | while (i()) { | ~^~ $GECODE_HOME/include/gecode/int/int-set-1.hpp:62:22: error: ‘class std::vector<int>’ has no member named ‘min’ 62 | d[n].min = i.min(); d[n].max = i.max(); size += i.width(); | ~~^~~ $GECODE_HOME/include/gecode/int/int-set-1.hpp:62:42: error: ‘class std::vector<int>’ has no member named ‘max’ 62 | d[n].min = i.min(); d[n].max = i.max(); size += i.width(); | ~~^~~ $GECODE_HOME/include/gecode/int/int-set-1.hpp:62:59: error: ‘class std::vector<int>’ has no member named ‘width’ 62 | d[n].min = i.min(); d[n].max = i.max(); size += i.width(); | ~~^~~~~ $GECODE_HOME/include/gecode/int/int-set-1.hpp:63:14: error: no match for ‘operator++’ (operand type is ‘std::vector<int>’) 63 | ++n; ++i; | ^~~
完整代码
#include <vector> #include <gecode/int.hh> #include <gecode/search.hh> #include <gecode/minimodel.hh> using namespace Gecode; class Class : public Space { public: std::vector<int> values = {2, 4, 6, 8}; IntVar i; Class() : i(*this, IntSet(values)) { } // search support Class(Class& s) : Space(s) { i.update(*this, s.i); } virtual Space* copy(void) { return new Class(*this); } // print solution void print() { std::cout << i << "\n"; } }; int main(int argc, char* argv[]) { Class* c = new Class; DFS<Class> e(c); delete c; while (Class* s = e.next()) { s->print(); delete s; } return 0; }
编译命令
g++ -std=c++20 -O3 -I $GECODE_HOME/include -L$GECODE_HOME/lib -lgecodesearch -lgecodeminimodel -lgecodeint -lgecodekernel -lgecodesupport bla.cc
问题分析与解决
误解点
你对IntSet的初始化方式理解有误:Gecode的IntSet不支持直接传入std::vector
编译器报错的原因是,它匹配到了IntSet的模板构造函数template<class I> IntSet(I& i),这个构造函数期望传入的是一个区间迭代器类型(具备operator()、min()、max()等成员方法),但std::vector显然不满足这些要求,因此触发一系列编译错误。
解决方法
有两种可行的修正方式:
使用vector的迭代器初始化IntSet
将构造函数中的IntSet(values)改为IntSet(values.begin(), values.end()),让IntSet通过迭代器遍历vector中的元素来构建集合:Class() : i(*this, IntSet(values.begin(), values.end())) { }直接使用初始化列表(无需vector)
如果不需要保留std::vector变量,可以直接用初始化列表传入IntSet:Class() : i(*this, IntSet({2, 4, 6, 8})) { }
修正后的代码即可正常编译运行,IntVar会被正确初始化为只能取{2,4,6,8}中的值。
内容的提问来源于stack exchange,提问作者Krishna
相关产品推荐
相关产品推荐

