我尝试编译简单程序
int main(int argc, char* argv[]) {
std::ifstream strings(std::string(argv[1]));
std::string line;
while (!strings.eof()) {
strings >> line;
}
}
并得到特殊错误:
error: request for member ‘eof’ in ‘strings’, which is of non-class type ‘std::ifstream(std::string*) {aka std::basic_ifstream<char>(std::basic_string<char>*)}’
如果我改为
std::ifstream strings(argv[1]);
所有编译都很好。
这里发生了什么?编译器是gcc 4.7和4.9。
答案 0 :(得分:4)
这有时被称为最烦恼的解析:strings
的声明被解释为函数声明,将指针(表示为数组)作为其参数。为了更清楚,我将删除一些在函数声明中冗余的括号:
std::ifstream strings(std::string argv[1]);
,由古老的数组/指针混淆规则,相当于
std::ifstream strings(std::string * argv);
与错误消息中提到的类型匹配。
从C ++ 11开始,你可以使用大括号初始化来解决这个问题:
std::ifstream strings{std::string(argv[1])};
^ ^
在历史方言中,你需要更多的冗长:
std::ifstream strings = std::ifstream(std::string(argv[1]).c_str());
请注意,在C ++ 11之前,您无法将std::string
直接传递给构造函数,但需要c_str()
才能获得C样式的字符串。
正如你所说,你可以简单地在任何C ++方言中传递argv[1]
作为参数,完全避免无理解析。