我正在尝试使用三元运算符清理一些代码,并且遇到了一些我无法理解的编译器错误。
我以前的代码看起来像这样,运行正常。
if(!inFile.good())
throw -2;
getline(inFile, inLine);
而我正在尝试使用此代码清理它。
(inFile.good()) ? getline(inFile, inLine) : throw -2;
但我收到以下错误。
g++ -w -o test orange_test.cpp
In file included from orange_test.cpp:4:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/iostream:39:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/streambuf:558:31: error: base class 'std::__1::ios_base' has private
copy constructor
_LIBCPP_EXTERN_TEMPLATE(class basic_ios<char>)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__config:462:54: note: expanded from macro '_LIBCPP_EXTERN_TEMPLATE'
#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/ios:305:5: note: declared private here
ios_base(const ios_base&); // = delete;
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/istream:1706:31: note: implicit default copy constructor for
'std::__1::basic_ios<char>' first required here
_LIBCPP_EXTERN_TEMPLATE(class basic_istream<char>)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__config:462:54: note: expanded from macro '_LIBCPP_EXTERN_TEMPLATE'
#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
^
./orange_model.hpp:145:23: note: implicit default copy constructor for 'std::__1::basic_istream<char>' first required here
(inFile.good()) ? getline(inFile, inLine) : throw -2;
^
1 error generated.
make: *** [main] Error 1
我无法理解它。是否存在一些我不知道的三元运算符或范围的限制?任何帮助或见解将不胜感激。 提前致谢, 最大
修改
从看到它的主要错误似乎是
error: base class 'std::__1::ios_base' has private copy constructor
它抱怨std :: getline(inFile,inLine)函数。
答案
此代码使其顺利运行。谢谢大家!
inFile.good() ? (void) getline(inFile, inLine) : throw -2;
答案 0 :(得分:6)
当一边是throw
时,三元运算符有一个特殊的规则。该规则的一部分是结果始终是临时右值,而不是引用。因此编译器需要复制getline()
返回值,这会失败,因为流是不可复制的。
您可以显式丢弃getline()
返回值,以避免复制尝试:
inFile? (void)getline(inFile, inLine) : (throw -2);
但是,我不同意你的清理尝试。原件更容易理解和维护。
另外,您的意思是在inFile
之前或之后测试getline()
的优点吗?你可以做到
getline(inFile, inLine) || (throw -2);
其他惯用语是perl的something or die "Error message"
答案 1 :(得分:2)
如果您设置了三元条件(我个人不同意),您必须阻止throw()
部分复制(请参阅Ben的答案),您可以通过制作该部分使用逗号运算符评估参考,就像getline
部分一样:
inFile.good() ? getline(inFile, inLine) : (throw -2, inFile);
错误的来源是std::istream
的复制构造函数是私有的,以防止复制,导致该尝试复制失败。仅使用不带逗号运算符的throw
即可使用1
代替getline
调用。
getline
返回您传入的istream &
(inFile
),最后一部分评估投掷,丢弃结果,并评估并使用inFile
作为最终版本值。除此之外,执行throw时,执行不会继续评估inFile
,因此它不会对正在运行的代码的逻辑产生影响。
答案 2 :(得分:-1)
你不应该使用投掷的“返回值”。