0

/* 感谢任何可能试图回答这个问题的人。我真的不想在这里浪费任何人的时间,但我已经为此苦苦挣扎了大约三天。我意识到对于理解它的人来说这可能非常简单。我已经尝试了我能想到的几乎所有可能的组合,但仍然会出现编译器错误。

C:\random\RNDNUMTEST.cpp(41) : 错误 C2102: '&' 需要左值

我正在尝试将指针作为参数传递给成员函数 fstream.open() 的函数 makeRndmNumber()。我想打开 RNDNUMTEST.cpp 中的文件,然后将其传递给 makeRndmNumber() 以便可以以某种方式对其进行修改。我在网上寻求帮助,包括这个网站,但我觉得我忽略了一些重要或简单的东西,或者我完全错过了这个概念。

这不是作业,我不是大学生。虽然我确实为此上过学,但我已经有 10 多年没有做过任何编程了,而且我从一开始就没有真正理解这一点。任何建议,将不胜感激。

// These are only excerpts from the actual files.

// RndmNum_Class.h  file

typedef void(fstream::*fStream_MPT)(const char*);    // fStream_MPT (Member Pointer Type)

class RandomNumber {

public: 

    RandomNumber();
    ~RandomNumber() {};
    static void loadDigits(double, double, char array[]);
    static int getLastNDigits(char array[], int);
    static int makeRndmNumber(int, int, fStream_MPT);
};

//*************************************************************8

//RndmNum_Class.cpp  file

int RandomNumber::makeRndmNumber(int seed, int _fileSize, fStream_MPT FILE) {

    ......

}

//**************************************************************/

// RNDNUMTEST.cpp  file

#include "RndmNum_Class.h"

int main() {  

    const char* RNDM_FILE = "c:\\RandomFile.txt";

    fstream FStream_Obj;
    // FStream_Obj.open(RNDM_FILE);

    fStream_MPT FileMembPtr = &FStream_Obj.open(RNDM_FILE);
        //fStream_MPT FileMembPtr = &fstream::open;

    int seed = 297814;
    int size = 20000;
    cout << RandomNumber::makeRndmNumber(seed, size, FileMembPtr);

    return 0;
}
4

3 回答 3

1

this:&FStream_Obj.open(RNDM_FILE)不是获取函数的地址,而是试图获取对该函数的调用的返回值的地址。但是该函数返回void,因此出现错误消息。

于 2012-01-07T02:34:01.063 回答
1

首先,将函数定义从 更改typedef void(fstream::*fStream_MPT)(const char*);typedef void(fstream::*fstream_MPT)(const char*,ios_base::openmode),您忘记了一个默认参数。

根据您的评论更改fStream_MPT FileMembPtr = &FStream_Obj.open(RNDM_FILE);fStream_MPT FileMembPtr = &fstream::open;,并向 makeRndNumber 添加一个附加参数,一个指向要操作的 fstream 的指针。

int RandomNumber::makeRndmNumber(int seed, int _fileSize, fStream_MPT FILE, fstream *file)               
{

    ((*file).*FILE)("ExampleText",ios_base::in | ios_base::out);

}

FILE = fstream::open;

编辑

这也可以用 std::function 对象做得更干净一些。

首先重新定义你的类型。

typedef std::function<void(const char*)> fStream_MPT;

然后当你分配时,一定要绑定你的对象。

fStream_MPT FILE = std::bind(&fstream::open,&file,std::placeholders::_1, ios_base::in | ios_base::out);

然后在您的函数中,您只需调用该函数

int RandomNumber::makeRndmNumber(int seed, int _fileSize, fStream_MPT FILE)               
{

    FILE("Example text");    
}
于 2012-01-07T02:42:53.510 回答
0

这没有任何意义:使用了成员函数指针,因此您可以在不知道调用哪个确切函数的情况下在某处应用不同的成员函数。这就像传递函数的名称(除了名称是在编译时解析的)。看来这不是你想做的!

即使你能正确获取函数的地址(而不是试图获取调用结果的地址open()),它也不会起作用,因为std::fstream::open()它需要两个参数:第二个参数用于开放模式,默认为std::ios_base::in | std::ios_base::out.

我不太确定你真正想要什么,但似乎你想传递文件流。执行此操作的正常方法是将对 a 的引用std::iostream作为参数传递给函数。好吧,实际上您可能希望std::ifstream最初使用 a 并因此将参数传递为std::istream&.

于 2012-01-07T02:41:08.410 回答