Как избавиться от «ошибки вызова соответствующей функции» при переборе потокового буфера? - PullRequest
2 голосов
/ 03 июня 2019

Я пытаюсь сохранить двоичные данные, которые должны иметь тип std :: complex , в вектор, перебирая каждый элемент буфера потока.Тем не менее, я получаю сообщение об ошибке:

no matching function for call to ‘std::istreambuf_iterator<std::complex<float> >::istreambuf_iterator(std::ifstream&)’
 std::for_each(std::istreambuf_iterator<std::complex<float> >(i_f1),

Я пытался найти решение, но не могу найти ничего, что будет работать.Я также пытаюсь следовать примеру, приведенному в Как прочитать весь поток в std :: vector? .Кроме того, я компилирую с использованием g ++ и -std = c ++ 11.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cmath>
#include <boost/tuple/tuple.hpp>
#include <algorithm>
#include <iterator>

int main(){

    //path to files
    std::string data_path= "/$HOME/some_path/";

    //file to be opened
    std::string f_name1 = "ch1_d2.dat";


    std::ifstream i_f1(data_path + f_name1, std::ios::binary);
    if (!i_f1){
        std::cout << "Error occurred reading file "<<f_name1 <<std::endl;        std::cout << "Exiting" << std::endl;
        return 0;
     } 

    //Place buffer contents into vector 
    std::vector<std::complex<float> > data1;

    std::for_each(std::istreambuf_iterator<std::complex<float> >(i_f1), 
        std::istreambuf_iterator<std::complex<float> >(), 
        [&data1](std::complex<float> vd){
        data1.push_back(vd);
        });

   // Test to see if vector was read in correctly
   for (auto i = data1.begin(); i != data1.end(); i++){
        std::cout << *i << " ";

    }

    i_f1.close();
    return 0;
}

Я совершенно растерялся из-за того, что я делаю неправильно, и поэтому задаюсь вопросом, почему

std::istreambuf_iterator() 

не принимает поток, который я передаю в качестве параметра?Кроме того, сообщение об ошибке сбивает меня с толку, поскольку, по-видимому, это означает, что я вызываю функцию неправильно или несуществующую функцию.

Спасибо

Ответы [ 2 ]

4 голосов
/ 03 июня 2019

Возможно, вы используете не тот инструмент для работы.

Вы пытаетесь использовать буферный итератор , который перебирает составляющие потока буфера . Но вы говорите своему компьютеру, что буфер является одним из complex<float> s & hellip; это не так Буфер ifstream имеет char с. Следовательно, конструктор, который вы пытаетесь использовать (тот, который принимает ifstream с буфером complex<float>), не существует.

Вы можете использовать istream_iterator для выполнения итерации в формате , то есть использовать магические силы потока (в данном случае, лексически интерпретируя входные данные как complex<float> s) вместо непосредственного доступа к его базовым байтам. .

Вы можете прочитать больше на предыдущий вопрос "разница между istreambuf_iterator и istream_iterator" .

Пример, на который вы ссылались, также объясняет это.

4 голосов
/ 03 июня 2019

Вы хотите прочитать std::complex из i_f1 (что является std::ifstream), используя operator>> для std::complex, поэтому вам нужно std::istream_iteratorвместо std::istreambuf_iterator 1 :

std::for_each(std::istream_iterator<std::complex<float> >(i_f1), 
    std::istream_iterator<std::complex<float> >(), 
    [&data1](std::complex<float> vd){
        data1.push_back(vd);
    });

Ваш код может быть упрощен до:

std::vector<std::complex<float>> data1{
    std::istream_iterator<std::complex<float>>(i_f1), 
    std::istream_iterator<std::complex<float>>()};

1 std::istreambuf_iterator используется для итерации символа на символ, например, std::basic_istream, а не для итерации с использованием перегрузок operator>>.

...