C++ - 无法在三元运算符内调用内联 std::cerr

C++ - Unable to call inline std::cerr inside of a ternary operator

我正在尝试制作一个非常简单的 setter 方法,在设置之前检查 start 值是否不高于 end 值。

这是基本代码:

if (start <= this->end) {
    this->start = start;
} else {
    cerr << "Start cannot be higher than end." << endl;
}

我尝试使用像这样的内联 if 语句来简化方法:

(start <= this->end) ? (this->start = start) : (cerr << "Start cannot be higher than end." << endl);

但 IntelliSense 告诉我以下问题:function "std::basic_ostream<_Elem, _Traits>::basic_ostream(const std::basic_ostream<_Elem, _Traits> &) [with _Elem=char, _Traits=std::char_traits<char>]" cannot be referenced -- it is a deleted function

呃,我对“删除函数”与将简单的 if 语句转换为内联语句有什么关系感到有点困惑。需要一些帮助。谢谢!

真假语句的类型必须匹配。

尝试将 , this->start(逗号运算符,然后 this->start)添加到错误大小写以匹配类型:

(start <= this->end) ? (this->start = start) : (cerr << "Start cannot be higher than end." << endl, this->start);

顺便说一句,我的建议是如果你想在一行中写 if 语句,而不是像这样使用条件运算符:

if (start <= this->end) this->start = start; else cerr << "Start cannot be higher than end." << endl;

三元条件表达式 a ? b : c 是一个 表达式 ,因此不等同于 if (a) { b } else { c }.

因为它是一个表达式,所以它必须有一个类型(并且,如果该类型不是 void,它也有一个值)。这就是为什么您可以在赋值的 right-hand 侧(甚至在某些情况下甚至是 left-hand 侧)放置三元条件。

条件表达式的类型由其第二个和第三个操作数的类型决定。如果它们具有相同的类型,那么结果就是该类型。如果没有某种“明确的”类型可以将两种操作数类型转换为,则三元表达式不会默认为 void 结果;它反而会导致编译错误。

在你的例子中,两个操作数是:

  • (this->start = start)
  • (cerr << "Start cannot be higher than end." << endl)

我假设前者有一些数字类型(this->start 的类型),而后者有 std::ostream& 类型。这两种类型都没有规范的“通用类型”,或者说,三元运算符没有“明显”的结果类型,出现编译错误。

if 语句可以解决这个问题。如果你坚持使用条件运算符,你可以这样做:

(start <= this->end)
? void(this->start = start)
: void(cerr << "Start cannot be higher than end." << endl);

这里,第二个和第三个表达式都转换为 void,因此整个三元表达式的结果类型为 void.

请注意,您不能将 breakreturn 之类的内容作为操作数之一。 condition ? void(return foo) : void(return bar) 将不起作用,因为 return <expr> 是一个 语句 ,而不是一个表达式。它没有类型,甚至没有 void。在这种情况下,您只能使用 if 语句。但是,您可以在条件表达式中使用 throw,因为 throw <expr> 是一个表达式。