我刚刚开始学习c++ 11,我有这个头文件:
#pragma once
#include <string>
#include <fstream>
#include <sstream>
class Parser
{
public:
Parser();
~Parser();
void Parse(const std::string& path);
private:
std::ifstream inFile;
void LoadFile(const std::string& path);
void Process(const std::istringstream& in);
};
和这个代码:
void Parser::LoadFile(const std::string& path)
{
if (!Exists(path))
throw std::exception("File not found.");
else
{
inFile.open(path);
std::string line;
while (std::getline(inFile, line))
{
// Input stream.
std::istringstream iss(line);
Process(&iss);
}
}
}
void Parser::Process(const std::istringstream& in)
{
}
但是我在Process(&iss);
行得到以下错误:
没有合适的构造函数可以从"std::istringstream *"std::basic_istringstream <char;std::>
我必须如何声明Process
方法?
Process(&iss);
iss
为std::istringstream
。当用于表达式时, &
是地址运算符。
&iss
表达式的结果是指向std::istringstream
或std::istringstream *
的指针。
void Process(const std::istringstream& in);
声明该函数以对const std::istringstream &
的引用作为形参,而不是指针。
在声明上下文中, &
表示引用类型。
&
在表达式或声明中使用时具有不同的含义。事实上,在表达式中,&
可以完全表示其他含义,这取决于它出现的位置。
&
字符在c++中有多种用途(有时非常令人困惑)。它可以用作位与操作符、寻址操作符,还可以在函数声明/定义中声明应通过引用传递给定形参。
在您的示例中,声明void Process(const std::istringstream& in);
是第三种情况—并且很好(可能使用const
修饰符1除外)。然而,在Process(&iss);
调用中,&
是一个地址操作符,并且您试图将指针传递给iss
变量(如果声明为void Process(const std::istringstream* in);
,则可以)。
当一个函数被声明为通过引用接受参数时(就像你的 1正如在评论中提到的,读取Process
一样),那么你只需要提供一个实际的变量/对象作为对该函数的任何调用的相应参数-编译器将为你提供引用。istringstream
对象(可能)会修改它,因此const
限定符可能会在您最不期望的时候破坏代码。(例如,只是在Process
的主体中添加一些伪代码,如:int i; in >> i;
将生成编译器错误;删除const
限定符可以解决这个问题。)