2015-04-24 2 views
5

Ich möchte den Inhalt eines ifstream leseng ++ 4.6.3 Inhalt einer Datei in Zeichenfolge Lesen Parsen Mehrdeutigkeit

#include <vector> 
#include <iterator> 
#include <fstream> 

std::ifstream stream; 
std::vector<char> buf(std::istreambuf_iterator<char>(stream), 
    std::istreambuf_iterator<char>()); 

Aber dann, wenn ich sage:

if(buf.size()) 
... 

ich einen Fehler

error: request for member 'size' in 'buf', which is of non-class type 'std::vector<char, std::istreambuf_iterator<char, std::char_traits<char> > >(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)())' 

So ist der Compiler denkt, ich bin eine Funktion statt eines vector<char> erklärt. Wie kann ich es zum Laufen bringen?

ich kompilieren mit -std=c++0x mit g++-4.6.3

Diese Frage ist mehr über Begriffsklärung Parsen als einer Datei zu lesen.

+0

Ich denke, es ist ein Fall von MVP, IIRC die Lösung dafür ist, den zweiten Parameter in Klammern zu wickeln. – Borgleader

+1

Related: [Most vexing parse] (http://en.wikipedia.org/wiki/Most_vexing_parse). –

+0

@ashoalm Das ist ein falsches Duplikat, das Problem ist nicht, wie man die Datei liest, es ist eine Eigenart der Sprache, wo diese Deklaration als Funktion betrachtet wird, kein Objekt vom Typ std :: vector Borgleader

Antwort

5

Deshalb eine geschweifte Klammer für die Initialisierung verwendet werden soll:

std::vector<char> buf { 
         std::istreambuf_iterator<char>(stream), 
         std::istreambuf_iterator<char>() 
         }; 

In Ihrem Fall buf ist nicht ein Objekt — es ist eher eine Funktionsdeklaration. Suche nach vexing Parse in C++ um die Erklärung zu wissen, warum es eine Funktion Deklaration ist.Es gibt ziemlich viele Hunderte von Themen zu diesem Thema.


In Ordnung. Hier ist, was passiert mit Ihrem Code. Dieser Code:

std::vector<char> buf(std::istreambuf_iterator<char>(stream), 
         std::istreambuf_iterator<char>()); 

wird vom Compiler als Funktionsdeklaration gesehen, wobei gilt:

  • der Funktionsname ist buf die std::vector<char> zurückgibt.
  • es nimmt zwei Parameter von Typen:
    • std::istreambuf_iterator<char>(stream), die des Schreibens std::istreambuf_iterator<char> stream nur eine andere Art ist (Pars sind in diesem Fall überflüssig).
    • std::istreambuf_iterator<char>(), die eine Funktion Typ ist wieder (Pars sind nicht überflüssig in diesem Fall) —, die zu einem Funktionszeigertyp abklingt, auf eine Funktion zeigen:
      • , die und das Rück std::istreambuf_iterator<char> nichts nimmt

So Ihr Code b ecomes das:

std::vector<char>       //return-type 
buf          //function-name 
(
    std::istreambuf_iterator<char> stream, //1st (named) parameter 
    std::istreambuf_iterator<char> (*)() //2nd (unnamed) parameter 
); 

Hoffnung, die hilft.

+0

ok, warum kompiliert dann folgendes: 'std :: vector b; \t Std :: Vektor a (b.begin(), b.end()); \t if (a.größe()) { \t \t zurück 1; \t} ' – iggy

+2

@iggy, Das kann nicht eine Funktion Erklärung sein. Der andere könnte. – chris

+1

Wenn Sie bereits eine einheitliche Initialisierung verwenden, können Sie das zweite Argument durch '{}' ersetzen :) – chris

Verwandte Themen