2017-02-09 5 views
1

Я пытаюсь прочитать двоичный файл, полный std::complex<float>. Я попытался следующий код, as suggested in this SO answer:Не удается получить векторный размер при построении из istreambuf_iterator

#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; 
} 

И я получаю следующее сообщение об ошибке компиляции:

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> > (*)())' 

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

Любые объяснения для этого?

+2

Большинство Vexing Parse? – WhiZTiM

ответ

2

Вы ударили C++ Most Vexing Parse. You заявление было расценено как объявление функции:

Вы можете:

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(); 
} 

Или использовать унифицированный Brace инициализации (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(); 
} 

Живая Here

+0

@WiinZTim. конструктор 'T object {}' как конструктор называется ** прямой инициализацией ** или ** равномерной инициализацией Brace **? –

+0

Инициализация фигурной скобки не работает: нет соответствующей функции для вызова «std :: vector > :: vector (<список инициализаторов, заключенных в фигурные скобки)) ' –

+0

Фактически обе предложенные реализации дают ошибки компиляции , Я считаю, что первый из-за отсутствия поддержки для комплекса в конструкторе istreambuf_iterator –

4

В ответ, который вы скопировали, показывает, как читать сырые символы из потока в буфер. Это правильное использование istreambuf_iterator.

Вы пытаетесь извлечь комплексные числа из потока. Это совершенно другая операция, которая включает в себя чтение символов , а затем их анализ operator<<. Это не то, для чего стоит istreambuf_iterator. Тип istreambuf_iterator<complex<float>> попытается извлечь символы типа complex<float> из basic_streambuf<complex<float>>, что является бессмыслицей. Это не тип символа, и вы не можете иметь streambuf, содержащий комплексные числа в качестве своих необработанных символов.

istreambuf_iterator предназначен для чтения отдельных символов из streambuf, а не для синтаксического анализа символов и интерпретации их как (сложных) чисел или других типов.

Вы должны использовать std::istream_iterator<X> для извлечения X значения из IStream, поэтому после того, как вы исправить наиболее неприятный разобрана, вам нужно использовать std::istream_iterator<std::complex<float>> как тип итератора.