从 linux 到 windows 的 C++:'不计算为常数'
Posted
技术标签:
【中文标题】从 linux 到 windows 的 C++:\'不计算为常数\'【英文标题】:C++ from linux to windows: 'does not evaluate to a constant'从 linux 到 windows 的 C++:'不计算为常数' 【发布时间】:2017-06-15 09:03:42 【问题描述】:我正在尝试将此功能从 Linux 移植到 Windows:
template<class TDescriptor, class F>
bool TemplatedVocabulary<TDescriptor,F>::loadFromBinaryFile(const std::string &filename)
fstream f;
f.open(filename.c_str(), ios_base::in|ios::binary);
unsigned int nb_nodes, size_node;
f.read((char*)&nb_nodes, sizeof(nb_nodes));
f.read((char*)&size_node, sizeof(size_node));
f.read((char*)&m_k, sizeof(m_k));
f.read((char*)&m_L, sizeof(m_L));
f.read((char*)&m_scoring, sizeof(m_scoring));
f.read((char*)&m_weighting, sizeof(m_weighting));
createScoringObject();
m_words.clear();
m_words.reserve(pow((double)m_k, (double)m_L + 1));
m_nodes.clear();
m_nodes.resize(nb_nodes+1);
m_nodes[0].id = 0;
char buf[size_node];// fails
int nid = 1;
while (!f.eof())
f.read(buf, size_node);
m_nodes[nid].id = nid;
// FIXME
const int* ptr=(int*)buf;
m_nodes[nid].parent = *ptr;
//m_nodes[nid].parent = *(const int*)buf;
m_nodes[m_nodes[nid].parent].children.push_back(nid);
m_nodes[nid].descriptor = cv::Mat(1, F::L, CV_8U);
memcpy(m_nodes[nid].descriptor.data, buf+4, F::L);
m_nodes[nid].weight = *(float*)(buf+4+F::L);
if (buf[8+F::L]) // is leaf
int wid = m_words.size();
m_words.resize(wid+1);
m_nodes[nid].word_id = wid;
m_words[wid] = &m_nodes[nid];
else
m_nodes[nid].children.reserve(m_k);
nid+=1;
f.close();
return true;
这一行:
char buf[size_node];
不会编译,报错:
expression did not evaluate to a constant
.
我尝试过使用:
std::vector<char> buf(size_node)
和:
char buf[size_node] = new char[];
但我看到了同样的错误。似乎这与运行时间常数与编译时间常数有关,如此处的答案所述:
Tuple std::get() Not Working for Variable-Defined Constant
但我不确定在这种情况下如何解决它。谢谢。
【问题讨论】:
GCC 支持可变长度数组作为扩展(这是你所拥有的),而标准 C++ 不支持。这就是为什么您应该始终使用-pedantic
构建的原因。我不知道您如何尝试vector
,但它应该可以工作。
C++ 没有variable-length arrays。一些编译器将其添加为语言的扩展。请改用std::vector
。
其他几件事:数组索引是从零开始的。 size_node
元素的数组(或向量)具有从 0
到 size_node - 1
(含)的索引。然后阅读Why is iostream::eof inside a loop condition considered wrong?
另见How do compilers treat variable length arrays和How does GCC implement variable-length arrays?
【参考方案1】:
应该是
char *buf = new char[size_node];
使用后记得删除内存。
或者,只需使用std::vector
。它更安全。
std::vector<char> buf(size_node);
那么你必须改变buf
的使用方式。例如:
f.read(buf, size_node);
应该变成
f.read(buf.data(), size_node); //Only C++11
【讨论】:
对于那些不喜欢清理自己的内存分配并且由于某种原因不愿意使用vector的人,你可以做auto buf = std::make_unique<char[]>(size_node);
之类的事情,虽然你不能完全对待它就像一个普通的旧数组。
谢谢!完美。
@anti : 如果此答案正确,请标记为正确。
完成。再次感谢您。以上是关于从 linux 到 windows 的 C++:'不计算为常数'的主要内容,如果未能解决你的问题,请参考以下文章
将数据序列化代码从 C++ linux/mac 移植到 C++ windows