1. ホーム
  2. c++

[解決済み] エラー C2228: '.size' の左側にはクラス/構造体/ユニオンが必要です。

2022-02-07 10:52:37

質問

vectorの "S "を呼び出すと、次のようなコンパイラエラーが発生します。 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;
}

解決方法は?

信じられないかもしれませんが、この行は ではありません。 のインスタンスを宣言しています。 std::vector という名前の results で、beginとendのイテレータをとってコンストラクタを呼び出す。

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

これは実際に は関数を宣言しています。 という results というパラメータを受け取り、そのパラメータは actualLineStream と別の無名パラメータがあり、どちらも型は std::istream_iterator<int> .

一般にC++では、何かが関数のように見える場合、それは関数のように解析されます。これはCとの後方互換性のためなのですが、あまりにも直感的であるため、これには独自の名前がついています。 最も厄介な構文解析。 . コンパイラによっては、最も厄介な構文解析に遭遇すると警告を発するものもあります。

この2行が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

これを修正するには、引数の1つの周りにさらに括弧を追加します。

//                         +--------- 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);