2014-09-30 3 views
-2
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). Есть ли способ бросить это или есть другой способ, который мне нужно отформатировать, чтобы он был вложен? (Для этого конкретного кода я фактически фокусируюсь на гнездовании тернарного оператора)троичного Оператор C++ Ostream в строку несовместимых операнды

+2

вероятно Вы имели в виду 'dayCheck == false' (который я думаю, что лучше записать в виде' dayCheck', если вы не следуете рекомендациям по стилю, в которых говорится: «Используйте перечисления вместо булевых, чтобы указать, какую альтернативу использовать»). Это вопрос на ваш вопрос. – rici

+0

Спасибо за подсказку @rici – TeddyCode

ответ

0

Проблема заключается во втором тернарном выражении. Эти два случая не имеют одинакового типа возврата. Первые возвращает 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); 
1

Вы отсутствуют cout.

Кроме того, он делает код более читаемым, когда вы добавляете paranthesis в подходящих местах.

Использование:

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 
0
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)); 

Так что, казалось, чтобы исправить эту проблему и Рождество возвращающая Int но теперь он никогда показывая не жизнеспособный преобразование из ostream в строку. Ошибка теперь появляется во всем разделе кода, начиная с (dayCheck = false).

(dayCheck == false) 
+0

Каков тип возврата этой функции, в которой мы находимся? Если это строка, то да, это не сработает. Вы хотели бы использовать 'std :: stringstream' вместо' std :: cout' и возвращать 'stringstream.string()'. – kmac

0

Здесь есть две связанные проблемы. Во-первых, обе ветви тернарного оператора должны иметь один и тот же тип (который является типом результата оператора), поэтому, если Christmas возвращает string, вы не можете иметь другую ветвь тернарного оператора, которая возвращает ostream&.

Вторая проблема заключается в том, что Christmas якобы возвращает string. (Я предполагаю, что оператор return фактически находится внутри функции Christmas.) Целью функции является не возвращение string, а скорее строка и, рекурсивно, другие строки в cout. Таким образом, единственными значимыми типами возврата являются ostream& или void. Но если вы сделаете такое изменение, вы обнаружите, что cout << Christmas(...) - это ошибка, потому что вы не можете отправить (<<) поток к себе.

Интересно посмотреть, как решить эту проблему с возвратом ostream&, хотя в конечном итоге это будет выглядеть совершенно иначе, чем ваша текущая программа. Ниже, по существу, недостатки, потому что функция, такая как Christmas, должна быть способна выводить на любой поток, но мы можем это исправить позже. Начнем с предположения, что функция возвращает ostream& и что она также выводится на тот же ostream. Так как функция возвращает ostream&, мы должны использовать, что вместо 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 */ 
} 

Если мы будем использовать <<, мы могли бы также быть последовательным. Предположим, мы хотим, чтобы начать все это прочь, написав:

std::cout << Christmas; 

Для этого нам нужны две вещи:

  1. объект класса, чтобы держать ostream&, который имеет функцию-член аналогичной к вышесказанному.

  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

Смежные вопросы