如何在逗号运算符中包含声明?

时间:2013-07-17 19:08:11

标签: c++ operators declaration

我有两个简单的测试线:

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

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

第一行有效,但第二行无法使用

进行编译
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 个答案:

答案 0 :(得分:6)

声明是语句而不是表达式。虽然可以在语句中放置表达式,但是不能在表达式中放置语句。因此,您不能以您上面描述的方式声明变量。您需要将其分成多个不同的陈述。

如果你真的需要这样做,我会感到惊讶。如果你这样做,你的设计可能会出现问题。

希望这有帮助!

答案 1 :(得分:5)

lambda允许在表达式中声明。所以这是可能的:

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

但这真的很奇怪 - 我认为这将在一些#define宏中使它看起来更接近正常。

答案 2 :(得分:5)

你应该看看Boost Phoenix(它有凤凰::让我们大致这样做)。请记住,Phoenix是eDSL,实际上是(嵌入式域特定语言)。

你可以做一个丑陋的伎俩并虐待lambdas:

cout<< ([]->int{ int i(8); return 8; })() <<endl;

答案 3 :(得分:4)

你做不到。这在C ++中是不可能的。您尝试这样做的事实也是代码味道。有些东西不在这里。

  

我想声明一些变量,获取它们的值并分配它们   从我班级的初始化列表到我的常量类成员   构造函数。不知道如何实现这一目标。

你没有说过你在使用这些值后声明的这些变量的意图,但我猜测一旦你完成了这些值,你就完成了变量。换句话说,它们是暂时的。

您编辑的示例表明我的假设是正确的。它还证实了代码的味道。根据您的(预期)代码,您将阅读该文件两次。

我认为最直接的方法是使用中间人,有点像工厂阶级。这样做的好处是只能读取一次文件,而不是现在的两倍。

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"));
}