2014-10-22 6 views
0

Сегодня я заменил низкоуровневый 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 дает какую-то гарантию?

ответ

2

ostreambuf_iterator - выходной итератор, std::distance требует ввода итераторов.

ошибка, возможно, немного загадочным, но это связано с difference_type быть typedef Эда void, т.е. пытается измерить расстояние между двумя ostreambuf_iterator с просто не имеет смысла, они даже не могут быть сравнены друг с другом.

+0

Wow, вы правы. Я никогда не замечал этого :) – djf

+0

Как ни странно, итераторы вывода value_type также выглядят 'void' - по крайней мере, для' std :: back_insert_iterator'. –

+0

@KerrekSB Предположительно, это означает, что некоторые другие операции терпят неудачу, например, 'алгоритм', который использует предикат. – user657267