【问题标题】:Ternary Operator C++ Ostream to String incompatible operands三元运算符 C++ Ostream 到字符串不兼容的操作数
【发布时间】:2014-11-24 14:57:14
【问题描述】:
return (dayCheck = false) ? cout << "On the " << day << 
"th Day of Christmas, My True Love Gave to Me: " 
<< endl << Christmas(day, count, true) : 
          (count != 0) ? cout << arr[count] << endl 
          << Christmas(day, count - 1, true) : 
                  Christmas(day + 1, day + 1, false);

我正在尝试做一个嵌套的三元运算符,但我想不出一种方法来使嵌套运算符中的操作数兼容,一个是 ostream,另一个是字符串 (char)。有没有办法投射这个,或者我需要另一种方式来格式化它以保持它嵌套? (对于这个特定的代码,我实际上关注的是三元运算符的嵌套)

【问题讨论】:

  • 您的意思可能是dayCheck == false(我认为最好写成!dayCheck,除非您遵循“使用枚举而不是布尔值来指示使用哪个替代方案”的样式推荐)。这是您问题的一个附带问题。
  • 感谢@rici 的提示

标签: c++ c++11 ternary-operator nested ostream


【解决方案1】:

您缺少cout

此外,当您在合适的位置添加括号时,它会使代码更具可读性。

用途:

return (dayCheck = false) ?

    // Add a pair of paranthesis for the first statement.
    (cout << "On the " << day << "th Day of Christmas, My True Love Gave to Me: " << endl << Christmas(day, count, true)) : 
    (count != 0) ?

    // Add a pair of paranthesis for the next first statement.
    (cout << arr[count] << endl << Christmas(day, count - 1, true)) : 

    // Add a pair of paranthesis for the last statement.
    (cout << Christmas(day + 1, day + 1, false));
  // ^^^^ The missing cout

【讨论】:

    【解决方案2】:

    问题在于第二个三元表达式。这两种情况没有相同的返回类型。 第一个返回一个ostream 对象

    cout << arr[count] << endl << Christmas(day, count - 1, true)
    

    第二个返回Christmas 返回的任何东西

    Christmas(day + 1, day + 1, false)
    

    要解决这个问题,让第二种情况也返回一个 ostream 对象:

    return (dayCheck = false) ? cout << "On the " << day << 
    "th Day of Christmas, My True Love Gave to Me: " 
    << endl << Christmas(day, count, true) : 
              (count != 0) ? cout << arr[count] << endl 
              << Christmas(day, count - 1, true) : 
                      cout << Christmas(day + 1, day + 1, false);
    

    【讨论】:

      【解决方案3】:
      return (dayCheck == false) ?
              (cout << "On the " << day << "th Day of Christmas, My True Love Gave to Me: " << endl << Christmas(day, count, true)) :
      
              (count != 0) ? cout << arr[count] << endl << Christmas(day, count - 1, true) :
      
              (cout << Christmas(day + 1, day + 1, false));
      

      所以这似乎解决了这个问题,Christmas 正在返回一个 int,但现在它显示从 ostream 到 string 的转换不可行。该错误现在出现在从 (dayCheck == false) 开始的整个代码部分中。

      (dayCheck == false)
      

      【讨论】:

      • 我们所在的这个函数的返回类型是什么?如果它是一个字符串,那么是的,这是行不通的。您可能想使用std::stringstream 而不是std::cout,并返回stringstream.string()
      【解决方案4】:

      这里实际上有两个相关的问题。首先,三元运算符的两个分支需要具有相同的类型(即运算符结果的类型),所以如果Christmas 返回一个string,则不能有另一个三元运算符分支返回ostream&amp;

      第二个问题正是Christmas 据称返回了string。 (我假设 return 语句实际上在 Christmas 函数内。)该函数的目的不是返回 string,而是返回一个字符串,然后递归地返回其他字符串到 cout。所以唯一有意义的返回类型是ostream&amp;void。但是如果你进行这样的更改,你会发现cout &lt;&lt; Christmas(...) 是一个错误,因为你不能向自己发送(&lt;&lt;)流。

      看看如何用ostream&amp; 返回来解决这个问题很有趣,尽管它最终看起来与您当前的程序完全不同。下面的内容本质上是有缺陷的,因为像Christmas 这样的函数应该能够输出到任何流,但我们可以稍后修复它。让我们首先假设该函数返回一个ostream&amp;,并且它也输出到相同的ostream。由于函数返回ostream&amp;,我们应该使用它而不是cout,所以我们可能会有大致这样的东西:

      std::ostream& Christmas(int day, int count, bool startStanza) {
        return (/* We're not finished */)
                  ? Christmas(/* the next line */) << /* This line */;
                  : std::cout;  /* FIXME */
      }
      

      但是,递归现在已经发生了翻天覆地的变化。递归调用发生在之前,我们设法将当前行发送到返回的ostream。所以我们实际上需要从结尾开始,然后递归到开头。事实证明,这并不难,我们甚至可以去掉布尔值:

      std::ostream& Christmas(int day, int count) {
        return day ? count <= day ? Christmas(day, count + 1) << gift[count] << '\n'
                                  : Christmas(day - 1, 1) << "On the "
                                                          << day
                                                          << " day of Christmas, "
                                                             "my true love gave to me:\n"
                   : std::cout; /* FIXME */
      }
      

      如果我们要使用&lt;&lt;,我们不妨保持一致。假设我们想通过以下方式开始整个事情:

      std::cout << Christmas;
      

      为此,我们需要两件事:

      1. 一个类对象,用来保存ostream&amp;,它的成员函数和上面类似。

      2. I/O manipulator,是一个函数,用来构造对象,调用其成员函数输出颂歌。

      这就是它的外观:

      class Singer {
          friend std::ostream& Christmas(std::ostream& out);
          Singer(std::ostream& out) : out(out) {}
          std::ostream& sing(int day, int count) {
            return day ? count <= day ? sing(day, count + 1) << (count == 1 && day > 1 ? "and " : "")
                                                             << gift[count - 1] << '\n'
                                      : sing(day - 1, 1) << "\nOn the "
                                                         << day
                                                         << "th day of Christmas, "
                                                            "my true love gave to me:\n"
                       : out;
          }
        private:
          std::ostream& out;
          static const char *gift[12];
      };
      
      std::ostream& Christmas(std::ostream& out) { return Singer(out).sing(12,1); }
      

      现场观看:http://coliru.stacked-crooked.com/a/1f801eadf8f5261e

      【讨论】:

        猜你喜欢
        • 2015-09-11
        • 2012-04-02
        • 2015-07-02
        • 1970-01-01
        • 2016-01-24
        • 2019-02-09
        • 1970-01-01
        • 2020-08-16
        • 1970-01-01
        相关资源
        最近更新 更多