2010-11-14 19 views
16

Vektörün size() numaralı telefonunu çağırırken bu derleyici hatasını alıyorum. Niye ya?hatası C2228: '.size' öğesinin solunda class/struct/union olmalıdır

#include <vector> 
#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
#include <cassert> 


using namespace std; 

class Vertex { 

    float firstValue; 
    float secondValue; 
    float thirdValue; 

    Vertex (float first, float second, float third){ 
      firstValue=first; 
      secondValue=second; 
      thirdValue=third; 
    } 

}; 


int main() 
{ 
    cout<<"This program loads a 3D .off object. \nEnter the name of the file that describes it "<<endl; 
    string inputFileName; 
    getline(cin, inputFileName); 

    ifstream inputFileStream; 

    inputFileStream.open(inputFileName.data()); 
    assert (inputFileStream.is_open()); 

    string actualLine; 

    for(;;){ 

     inputFileStream>>actualLine; 

     istringstream actualLineStream(actualLine); 



     std::vector<float> results(std::istream_iterator<int>(actualLineStream) 
         , std::istream_iterator<int>()); 

     int resultsIndex=0; 
     int resultsSize=results.size(); //WHY?? 

     while (resultsIndex<resultsSize){ 

     cout<<results[resultsIndex]<<endl; 
     } 


     if (inputFileStream.eof()) break; 

    } 


    ofstream outputChannel; 

    while (true){} // to keep on console view 
    return 0; 
} 

cevap

48

İster inanın ister inanmayın, bu hat bir başlangıç ​​ve bitiş yineleyici alarak kurucu çağırmak, results adlı std::vector bir örneğini bildirmiyor yapar:

std::vector<float> results(std::istream_iterator<int>(actualLineStream), 
    std::istream_iterator<int>()); 

Bu aslında bir işlev bildirirresults adlı, actualLineStream adlı bir parametre ve başka bir adsız parametre olan her ikisi de std::istream_iterator<int> türünü kullanır.

Genel olarak C++ 'da, eğer bir işlev bir işlev gibi görünüyorsa, bir tane gibi ayrıştırılır; C++ standardı bunu gerektirir. Bu gerçekten C ile geriye dönük uyumluluk içindir - ancak bu kendi başına bir isme sahip olduğu için çok tuhaftır: "most vexing parse". Bazı derleyiciler, en çok rahatsız edici ayrıştırmayla karşılaşırsa bile bir uyarı yayınlayacaktır.

Bu iki satır C++ eşdeğer olmadığı gerçeği ile ilgilidir:

Foo bar; // Declares an instance of Foo named bar 
Foo bar(); // Declares a function named bar that takes no parameters and returns a Foo 

, bunu düzeltmek için, argümanlardan biri etrafında daha parantez ekleyebilirsiniz:

//       +--------- Note extra parentheses!! ---------+ 
//       |           | 
//       V           V 
std::vector<float> results((std::istream_iterator<int>(actualLineStream)), 
    std::istream_iterator<int>()); 

Ya basitçe ayrı ayrı yineleyici beyan:

std::istream_iterator<int> resultsBegin(actualLineStream); 
std::istream_iterator<int> resultsEnd; 
std::vector<float> results(resultsBegin, resultsEnd); 
+4

Vay .. ben hiç düşünmemiştim olurdu. – andandandand

+0

Bu gönderiyi bulduğuma sevindim. Bu davranış korkunç. –

+0

Evet, şükürler olsun bunu buldum. Dizüstü bilgisayarımı pencereden dışarı atmaya hazırdım. – MikeTheLiar

6

sana this bugaboo isabet düşünüyorum . std::vector<float>'u döndüren yeni bir işlev olarak results bildirmeyi başardınız. Ben results beyan satırı değiştirirseniz:

std::vector<float> results = std::vector<float>(std::istream_iterator<int>(actualLineStream), std::istream_iterator<int>()); 

Bunu derlemek olabilir (GCC ile olsa da, YMMV)

İlgili konular