Reputation: 13254
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?
Upvotes: 1
Views: 302
Reputation: 21576
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
Upvotes: 3
Reputation: 171263
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.
Upvotes: 4