简体   繁体   中英

Cannot get vector size when constructed from istreambuf_iterator

I'm trying to read a binary file full of std::complex<float> . I tried the following code, as suggested in this SO answer :

#include <complex>
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <vector>


void readRawFile(const std::string inputFile){
    std::ifstream input(inputFile, std::ios::binary);
    std::vector<std::complex<float>> auxBuffer(std::istreambuf_iterator<std::complex<float>>(input), std::istreambuf_iterator<std::complex<float>>());
    std::cout << "Number of raw samples read: " << auxBuffer.size();
}

int main(){
    readRawFile("myRawFile.raw");
    return 0;
}

And I get the following compilation error:

In function 'void readRawFile(std::string)': 12:59: error: request for member 'size' in 'auxBuffer', which is of non-class type 'std::vector<std::complex<float> >(std::istreambuf_iterator<std::complex<float> >, std::istreambuf_iterator<std::complex<float> > (*)())'

I don't understand why can't I access the size method of a vector I just created without compilation errors. I suppose it has something to do with how the vector is being created, but it seems strange to me that it doesn't give an error there instead.

Any explanation for this?

The answer you copied shows how to read raw characters from a stream into a buffer. That's a correct use of istreambuf_iterator .

You are trying to extract complex numbers from a stream. That's a completely different operation, which involves reading the characters and then parsing them with operator<< . That's not what istreambuf_iterator is for. The type istreambuf_iterator<complex<float>> would try to extract characters of type complex<float> from a basic_streambuf<complex<float>> which is nonsense. That's not a character type, and you can't have a streambuf containing complex numbers as its raw characters.

istreambuf_iterator is for reading single characters from a streambuf, not for parsing characters and interpreting them as (complex) numbers or other types.

You need to use std::istream_iterator<X> to extract X values from an istream, so after you fix the most vexing parse, you need to use std::istream_iterator<std::complex<float>> as the iterator type.

You've hit C++'s Most Vexing Parse . You declaration was interpreted as a function declaration:

You can either:

void readRawFile(const std::string inputFile){
    std::ifstream input(inputFile, std::ios::binary);

    auto start = std::istream_iterator<std::complex<float>>(input);
    auto stop = std::istream_iterator<std::complex<float>>();

    std::vector<std::complex<float>> auxBuffer(start, stop);
    std::cout << "Number of raw samples read: " << auxBuffer.size();
}

Or use Uniform Brace Initialization (C++11):

void readRawFile(const std::string inputFile){
    std::ifstream input(inputFile, std::ios::binary);
    std::vector<std::complex<float>> auxBuffer{std::istream_iterator<std::complex<float>>(input), std::istream_iterator<std::complex<float>>()};
    std::cout << "Number of raw samples read: " << auxBuffer.size();
}

Live Here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM