Проверьте, является ли объект ostream cout или ofstream, c ++ - PullRequest
7 голосов
/ 23 июля 2010

Есть ли в C ++ способ проверить, является ли объект ostream cout или ofstream объектом?

Что-то вроде:

<code>ostream& output(ostream& out)
{
    if (out == cout)
        return out;
    else
    {
        out << "something different because its not going to the console" << endl;
        return out;
    }
}

Причина, по которой я хочу это сделать, заключается в том, что я хочу перегрузить оператор <<, чтобы сделать две разные вещи в зависимости от того, какой типstream, с которым он используется.

Можно ли просто дважды перегрузить оператор << каждый раз с другим типом потока?

Обновлено, чтобы лучше отражать намерения.

Ответы [ 4 ]

9 голосов
/ 14 марта 2011

Вы определенно продвинетесь дальше, проверив идентичность потокового буфера

if (s.rdbuf() == std::cout.rdbuf())

Это потому, что тривиально назначить потоки / псевдонимы буферам тривиально просто, см. http://www.cplusplus.com/reference/iostream/ios/rdbuf/ и книгу Josuttis

4 голосов
/ 23 июля 2010

Похоже, вы действительно хотите знать не о том, является ли поток cout, а о том, подключен ли базовый файловый дескриптор к терминалу? Если это так, вам нужен базовый дескриптор файла. К сожалению, вы не можете получить это от iostream. Если можно использовать cstdio вместо iostream, тогда вы можете. Если у вас есть файловый дескриптор, определить, пишете ли вы в терминал, просто, если посмотреть, возвращает ли tcgetattr () -1.

Кроме того, не позволяйте никому говорить, что вы не реализуете некоторую функциональность, которая вам нужна, потому что она бросает тень на чистоту какой-то утечки абстракции. Если вам действительно нужно другое поведение, то делайте то, что вам нужно, чтобы реализовать эту функциональность.

4 голосов
/ 23 июля 2010

Это возможно, проверив «идентичность» потока: if ( &out == &cout ) ....

Однако я сомневаюсь в полезности этого теста. Если ваша функция может обрабатывать любой выходной поток, зачем беспокоиться о том, какой поток он использует?

1 голос
/ 23 июля 2010

Я считаю, что изменение способа потоковой передачи на основе объекта, который вы передаете, - ужасная идея, которая полностью игнорирует весь смысл работы потоковых объектов.Итак, я бы создал класс-член или функцию, которая возвращает объект типа, который по-разному обрабатывает поток.Так, например, если вы хотите предоставить цветной поток, вы бы позвонили:

std::cout << myclass.colorstreamer << endl;

Редактировать:

Ваше предложение по обработке потоков - плохая идеяпотому что вы понятия не имеете, как другие люди будут использовать ваш код.Совершенно неинтуитивно для потока вести себя по-разному в зависимости от того, какой объект выполняет потоковую передачу.Я сравниваю это с наличием функции, которая возвращает другой результат в зависимости от того, кто ее вызвал, а не от того, каковы ее аргументы, хотя я признаю, что технически поток является аргументом.

Что касается того, как это сделать, этоодин из способов - создать colorstreamer, сделать этот новый класс членом myclass и сделать myclass членом colorstreamer, а затем сделать потоковый оператор colorstreamer другом myclass,Меня больше беспокоит семантика вызова функции (т. Е. Использование .colorstreamer для управления потоком, а не сам поток), чем вопрос о том, как ее реализовать.Мое предложение о том, как это реализовать, вполне возможно, плохой способ сделать это;мой C ++ ржавый.

...