我正在用c ++编写一个程序,它可以从std :: cin或std :: istringstream获取文件的输入(作为命令行arg传递给它)。它工作正常,并使用std :: istream *进行管理。我被告知这很糟糕,处理原始指针,所以我决定将它包装在std :: unique_ptr(即std :: unique_ptr)中。问题是它无法编译。至于我可以从错误中辨别出来,std :: istream已经保护自己不被用来分配内存。我试过谷歌搜索它,但我认为之前没有人发布过这样的问题(因为我只看到只引用std :: unique_ptr的问题)。有谁知道如何实现这个目标?
edit: errors: In file included from /usr/include/c++/4.8/iostream:40:0,
from /home/dtscode/Desktop/SLang/src/main.cpp:1:
/usr/include/c++/4.8/istream: In function ‘int main(int, char**)’:
/usr/include/c++/4.8/istream:606:7: error: ‘std::basic_istream<_CharT, _Traits>::basic_istream() [with _CharT = char; _Traits = std::char_traits<char>]’ is protected
basic_istream()
^
compilation terminated due to -Wfatal-errors.
make[2]: *** [CMakeFiles/slang.dir/src/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/slang.dir/all] Error 2
make: *** [all] Error 2
响应这一行:std :: unique_ptr Stream(new std :: istream());
我也试过它而没有调用istreams构造函数而且在unique_ptrs构造函数中没有任何东西
编辑2:
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <memory>
#include <lexer.hpp>
int main(int argc, char *argv[]) {
std::unique_ptr<std::istream> Stream(new std::istream());
std::vector<std::string> Arguments(argv, argv + argc);
switch(argc) {
case 1:
Stream = &std::cin;
break;
case 2:
Stream = new std::ifstream(Arguments[1]);
break;
case 3:
if(Arguments[1] == "-c") {
Stream = new std::istringstream(Arguments[2]);
break;
}
default:
std::cerr<<"error: invalid arguments."<< std::endl;
return 0;
}
Token::Lexeme CurrentToken = Token::Start;
while(*Stream) {
CurrentToken = getToken(Stream);
lex_debug();
}
if(Stream != &std::cin) {
delete Stream;
}
return 0;
}
答案 0 :(得分:6)
我说这只是一个非常糟糕的因素代码。为什么不这样:
void process_input(std::istream & is);
int main(int argc, char * argv[]) {
if (argc == 1) {
process_input(std::cin);
} else if (argc == 2) {
std::ifstream is(argv[1], "rb");
process_input(is);
} else if (argc == 3 && strcmp(argv[1], "-c") == 0) {
std::istringstream is(argv[2]);
process_input(is);
} else {
std::cerr << "Unrecognized invocation.\n";
return EXIT_FAILURE;
}
}
答案 1 :(得分:1)
您显示的错误是由于std :: istream构造函数调用,它是一个基类,无法实例化。即使代码确实编译了,std :: unique_ptr也是一个拥有指针,因此试图删除std :: cin会出现问题。你想要一个非拥有指针,所以原始指针或std :: weak_ptr是正确的。
编辑:如果可能,我建议改用引用。
答案 2 :(得分:0)
我经常选择这样的流:
#include <iostream>
#include <fstream>
#include <istream>
#include <sstream>
#include <vector>
int main(int argc, char *argv[])
{
std::vector<std::string> args(argv, argv + argc);
std::ifstream ifs(argc == 2 ? args[1]:"");
std::istringstream iss(argc == 3 ? args[2]:"");
std::istream& is = argc == 2 ? ifs : argc == 3 && args[1] == "-c" ? iss : std::cin;
while(is)
{
// process stream
}
}
这就是我避免使用指针的方法。