所以我正在运行这段示例代码:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main() {
ifstream inFile;
string str;
cout << "\nEnter file name : ";
cin >> str;
try {
inFile.open(str);
if(!inFile)
throw exception();
} catch(exception e) {
cout <<"\nAn exception was caught. file does not exist. ";
return 1;
}
return 0;
}
它给了我一个编译器错误:
test.cpp:14:13: error: no viable conversion from 'string' (aka 'basic_string<char>') to 'const char *'
inFile.open(str);
^~~
/usr/include/c++/4.2.1/fstream:517:24: note: passing argument to parameter '__s' here
open(const char* __s, ios_base::openmode __mode = ios_base::in)
我查看了函数原型:
void open (const char* filename,
ios_base::openmode mode = ios_base::in | ios_base::out);
void open (const string& filename,
ios_base::openmode mode = ios_base::in | ios_base::out);
为什么fstream :: open()期望一个const String / const char *?文件名可以从任何地方获取(来自用户,如上例中所示),在这种情况下,将str
转换为const string
也无济于事。
我能够通过使用str.c_str()
来使其工作,但有人可以帮助我理解为什么 const - 已经在文件打开方法中强制执行了吗?为什么不允许我按原样使用字符串,而不必使用char *或将其转换为c风格的字符串?
答案 0 :(得分:6)
您可以将非const
对象传递给采用const
引用的函数。
问题是您没有(或尚未启用)C ++ 11支持,因此缺少string
重载。如果您遇到2011之前的库,那么您唯一的选择是使用c_str()
来获取C风格的字符串指针。
答案 1 :(得分:3)
C ++ 11(使用-std=c++0x
或std=c++11
标志启用)
void open (const string& filename,
ios_base::openmode mode = ios_base::in | ios_base::out);
不会导致非const字符串对象出现任何问题。
const string &
有助于避免不必要的字符串对象复制
答案 2 :(得分:2)
open
占用const char*
的事实并不意味着您无法将其传递给常规char*
。 char*
可以转换为const char*
,而不是相反(除非你使用const_cast
,但这些都是邪恶的。)
这个声明只是说“open
将字符串作为输入,它承诺不会修改内容”。
答案 3 :(得分:2)
您的代码可以使用当前标准编译(C ++ 11),遗憾的是,我所知道的任何编译器都没有使用它。
答案 4 :(得分:1)
您误解了函数签名的语法:
为什么fstream :: open()期望一个const String / const char *?该 文件名可以从任何地方获得(来自用户,如在 上面的例子),并将str变成一个const字符串没有帮助 那种情况。
签名如下:
void open (const char* filename, ios_base::openmode mode = ios_base::in | ios_base::out);
void open (const string& filename, ios_base::openmode mode = ios_base::in | ios_base::out);
第一个重载需要const char*
(例如指向常量字符数组的指针)。
第二个重载需要const std::string&
(例如对常量std :: string的引用)。
字符串不是const std::string
,而是引用。它声明该函数不会修改字符串,并且您正在传递对原始的引用(而不是复制它)。您可以将非const字符串传递给需要const字符串而没有问题的函数(不需要转换/强制转换)。
原始问题的答案(为什么需要const char*
?)并不是那么复杂:流库和字符串库是由不同的人群并行开发的。在早期标准中,他们没有合并开发。这已在C ++ 11中得到解决。