错误C2228:'。size'的左边必须有class / struct / union

时间:2010-11-14 02:55:08

标签: c++ visual-studio-2008

调用vector size()时,我收到此编译器错误。为什么?

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

2 个答案:

答案 0 :(得分:51)

信不信由你,这行声明std::vector名为results的实例,调用构造函数接受开始和结束迭代器:

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

这实际上是声明一个名为results的函数,它接受名为actualLineStream的参数和另一个类型为std::istream_iterator<int>的未命名参数。

通常在C ++中,如果某个东西看起来像一个函数,它将被解析为一个; C ++标准需要它。这实际上是为了向后兼容C - 但这是违反直觉的,它甚至有自己的名字:"most vexing parse"。有些编译器甚至会在遇到最令人烦恼的解析时发出警告。

这与以下事实有关:这两行在C ++中并不相同:

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

要修复它,您可以在其中一个参数周围添加更多括号:

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

或者只是单独声明每个迭代器:

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

答案 1 :(得分:6)

我认为你点击了this bugaboo。您已设法将results声明为返回std::vector<float>的新函数。如果我将声明results的行更改为:

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

我可以编译它(使用GCC,但是,YMMV)