станд.:: endl имеет неизвестный тип при перегрузке оператора <<

Прием здесь не должен становиться зилотом.

Одна вещь отметить вот состоит в том, что никто в про лагере файловой системы не перечислил конкретную файловую систему. Это означает, что все от FAT16 до ZFS ловко бьет каждую базу данных?

истина - то, что много баз данных бьют много файловых систем, даже когда мы только говорим о необработанной скорости.

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

58
задан GManNickG 15 July 2009 в 22:10
поделиться

4 ответа

std :: endl - это функция, а std :: cout использует его, реализуя operator << , чтобы получить указатель на функцию с той же сигнатурой, что и std :: endl .

Там он вызывает функцию и пересылает возвращаемое значение.

Вот пример кода:

#include <iostream>

struct MyStream
{
    template <typename T>
    MyStream& operator<<(const T& x)
    {
        std::cout << x;

        return *this;
    }


    // function that takes a custom stream, and returns it
    typedef MyStream& (*MyStreamManipulator)(MyStream&);

    // take in a function with the custom signature
    MyStream& operator<<(MyStreamManipulator manip)
    {
        // call the function, and return it's value
        return manip(*this);
    }

    // define the custom endl for this stream.
    // note how it matches the `MyStreamManipulator`
    // function signature
    static MyStream& endl(MyStream& stream)
    {
        // print a new line
        std::cout << std::endl;

        // do other stuff with the stream
        // std::cout, for example, will flush the stream
        stream << "Called MyStream::endl!" << std::endl;

        return stream;
    }

    // this is the type of std::cout
    typedef std::basic_ostream<char, std::char_traits<char> > CoutType;

    // this is the function signature of std::endl
    typedef CoutType& (*StandardEndLine)(CoutType&);

    // define an operator<< to take in std::endl
    MyStream& operator<<(StandardEndLine manip)
    {
        // call the function, but we cannot return it's value
        manip(std::cout);

        return *this;
    }
};

int main(void)
{
    MyStream stream;

    stream << 10 << " faces.";
    stream << MyStream::endl;
    stream << std::endl;

    return 0;
}

Надеюсь, это даст вам лучшее представление о том, как эти вещи работают.

81
ответ дан 24 November 2019 в 18:48
поделиться

Потоки std не предназначены для разделения на подклассы, поскольку у них нет виртуальных методов, поэтому я не думаю, что вы зайдете слишком далеко с этим. Вы можете попытаться объединить std :: ostream для выполнения этой работы.

Чтобы заставить endl работать, вам необходимо реализовать версию operator << , которая принимает указатель на -функция, как обрабатываются такие манипуляторы, как endl , т.е.

UStream& operator<<( UStream&, UStream& (*f)( UStream& ) );

или

UStream& UStream::operator<<( UStream& (*f)( UStream& ) );

Теперь std :: endl - это функция, которая принимает и возвращает ссылку на std :: basic_ostream, так что это не будет работать напрямую с вашим потоком, поэтому вам нужно будет создать свою собственную версию, которая обращается к версии std :: endl в вашем агрегированном std :: iostream .

Изменить: Похоже, ответ GMan лучше.

3
ответ дан 24 November 2019 в 18:48
поделиться

См. здесь , чтобы узнать о лучших способах расширения IOStreams. (Немного устаревший и адаптированный для VC 6, поэтому вам придется отнестись к нему с недоверием)

Дело в том, что для того, чтобы заставить работать функторы (и endl, который выводит "\ n" и сбрасывает, является functor) вам необходимо реализовать полный интерфейс ostream.

4
ответ дан 24 November 2019 в 18:48
поделиться

Проблема в том, что std :: endl является шаблоном функции, как ваш оператор << является. Поэтому, когда вы напишете:

my_stream << endl;

, вам понравится, чтобы компилятор выводил параметры шаблона для оператора а также для endl . Это невозможно.

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

UIStream& operator<<(UIStream& os, std::ostream& (*pf)(std::ostream&));

(есть два других, заменив std :: ostream на std :: basic_ios и std :: ios_base , который вы также должны предоставить, если хотите разрешить все манипуляторы) и их реализация будет очень похожа на одну из ваши шаблоны. Фактически, настолько похожи, что вы можете использовать свой шаблон для такая реализация:

typedef std::ostream& (*ostream_manipulator)(std::ostream&);
UIStream& operator<<(UIStream& os, ostream_manipulator pf)
{
   return operator<< <ostream_manipulator> (os, pf);
}

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

36
ответ дан 24 November 2019 в 18:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: