1

2 つの簡単なテスト行があります。

cout<<(cout<<"ok"<<endl, 8)<<endl;

cout<<(int i(8), 8)<<endl;

最初の行は機能しましたが、2行目はコンパイルに失敗しました

error: expected primary-expression before 'int'

何らかの理由で、カンマ演算子で宣言が必要です。より具体的には、いくつかの変数を宣言し、それらの値を取得して、クラス コンストラクターの初期化リストから定数クラス メンバーに割り当てたいと考えています。以下は私の意図を示しています。コンマ演算子を使用して達成できない場合、別の提案はありますか?

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdlib>

using namespace std;

void readFile(const string & fileName, int & a, int & b)
{
    fstream fin(fileName.c_str());
    if (!fin.good()) {cerr<<"file not found!"<<endl; exit(1);}
    string line;
    getline(fin, line);
    stringstream ss(line);
    try {ss>>a>>b;}
    catch (...) {cerr<<"the first two entries in file "<<fileName<<" have to be numbers!"<<endl; exit(1);}
    fin.close();
}

class A
{
    private:
        const int _a; 
        const int _b; 
    public:
        A(const string & fileName)
            :   
            _a((int a, int b, readFile(fileName,a,b), a)),
            _b((int a, int b, readFile(fileName,a,b), b)) 
        {   
            /*  
            int a, b;
            readFile(fileName,a,b);
            _a = a;_b = b;
            */
        }   

        void show(){cout<<_a<<" "<<_b<<endl;}
};

int main()
{
    A a("a.txt");
    a.show();
}
4

4 に答える 4

5

ラムダを使用すると、式内で宣言できます。したがって、これは可能です:

std::cout << ([]{ int i(8); m_i = i; }(), 8) << std::endl;

しかし、これは非常に奇妙です。これは#define、通常の表示に近づけるためのマクロに含まれていると思います。

于 2013-07-17T19:12:18.110 に答える
5

Boost Phoenix を参照する必要があります (これにはおおまかにこれを行う phoenix::let があります)。Phoenix は実際には eDSL です (組み込みのドメイン固有言語)。

醜いトリックを実行して、ラムダを悪用することができます。

cout<< ([]->int{ int i(8); return 8; })() <<endl;
于 2013-07-17T19:12:58.433 に答える
4

それはいけません。これは C++ では不可能です。あなたがこれをやろうとしているという事実もコードの匂いです。何かがおかしい。

いくつかの変数を宣言し、それらの値を取得して、クラス コンストラクターの初期化リストから定数クラス メンバーに割り当てたいと考えています。これを達成する方法がわからない。

値を使用した後に宣言したこれらの変数で何をするつもりだったかは言いませんでしたが、値を使い終わったら、変数を使い終わったと思います。つまり、それらは一時的なものです。

あなたの編集された例は、私の仮定が正しいことを示唆しています。コードの匂いも確認。(意図した) コードに基づいて、ファイルを 2 回読み取ることになります。

これを行う最も簡単な方法は、ファクトリ クラスのような仲介を使用することです。これには、ファイルを 1 回だけ読み取ることができるという利点もあります。今は 2 回行っています。

void readFile (const std::string& fileName, int& a, int& b)
{
    // some magic
    a = 42;
    b = 314;
}

class FileReader
{
public:
    FileReader (const std::string fileName)
    :
        mFileName (fileName),
        mA (42),
        mB (314)
    {
        // something happens like reading the file
    }

    int GetA () const
    {
        return mA;
    }
    int GetB () const
    {
        return mB;
    }
private:
    int mA;
    int mB;
    std::string mFileName;
};

class A
{
private:
    const int mA;
    const int mB;
public:
    A (const FileReader& reader)
    :
        mA (reader.GetA()),
        mB (reader.GetB())
    {
    }
};

これを使用するFileReaderのは簡単です:

int main()
{
    A myA (FileReader ("somefile.txt"));
}
于 2013-07-17T19:32:01.750 に答える