带函数调用的C ++三元运算符

时间:2014-01-02 04:37:33

标签: c++ std ternary-operator

我正在尝试使用三元运算符清理一些代码,并且遇到了一些我无法理解的编译器错误。

我以前的代码看起来像这样,运行正常。

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;

3 个答案:

答案 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)

你不应该使用投掷的“返回值”。