Сегодня я заменил низкоуровневый C-стильный метод, который сохраняет буфер в файл. Все это выглядело так:Разница_имя ostreambuf_iterator <char> недействительна?
bool Profile::save(const char* path)
{
FILE* pFile = fopen(path, "w");
BOOST_SCOPE_EXIT((pFile)) {
fclose(pFile);
pFile=NULL;
} BOOST_SCOPE_EXIT_END
if(pFile == 0)
{
LOG_ERROR("could not open profile");
return false;
}
size_t nWriteSize = fwrite(DataBlock, 1, sizeof(DataBlock), pFile);
if(nWriteSize != sizeof(DataBlock))
{
LOG_ERROR("Only " << nWriteSize << " of " << sizeof(DataBlock) << "bytes written");
return false;
}
return true;
}
Этот метод на самом деле содержится ошибка, при которой было бы segvfault, если он не может найти файл, чтобы открыть (внутри BOOST_SCOPE_EXIT мы пренебрегли, чтобы проверить, если Pfile! = NULL). Поэтому я подумал, что я переписал все это в более идиоматическом стиле C++. Вот что я придумал:
bool Profile::save(const char* path)
{
std::ofstream profile(path, std::ios::out | std::ios::binary);
if(!profile)
{
LOG_ERROR("could not open " << path);
return false;
}
const char* pBeginOfBlock = reinterpret_cast<char*>(DataBlock);
const char* pEndOfBlock = reinterpret_cast<char*>(DataBlock + sizeof(DataBlock));
std::ostreambuf_iterator<char> begin_file = std::ostreambuf_iterator<char>(profile);
std::ostreambuf_iterator<char> end_file = std::copy(pBeginOfBlock,
pEndOfBlock,
begin_file);
const unsigned int BytesWritten = std::distance(begin_file, end_file);
if(BytesWritten != sizeof(DataBlock))
{
LOG_ERROR("Only " << BytesWritten << " of " << sizeof(DataBlock) << "bytes written");
return false;
}
return true;
}
Однако это не скомпилировано. Это дает мне ошибку на линии, где я стараюсь, чтобы получить расстояние до ostreambuf_iterators:
error: void value not ignored as it ought to be
Видимо difference_type ostreambuf_iterator из недействительна. Как я могу проверить, что все байты фактически были записаны в файл? Является ли проверка даже необходимой или std :: copy дает какую-то гарантию?
Wow, вы правы. Я никогда не замечал этого :) – djf
Как ни странно, итераторы вывода value_type также выглядят 'void' - по крайней мере, для' std :: back_insert_iterator'. –
@KerrekSB Предположительно, это означает, что некоторые другие операции терпят неудачу, например, 'алгоритм', который использует предикат. – user657267