Прием здесь не должен становиться зилотом.
Одна вещь отметить вот состоит в том, что никто в про лагере файловой системы не перечислил конкретную файловую систему. Это означает, что все от FAT16 до ZFS ловко бьет каждую базу данных?
№
истина - то, что много баз данных бьют много файловых систем, даже когда мы только говорим о необработанной скорости.
корректный план действий должен принять правильное решение для Вашего точного сценария, и сделать это, Вам будут нужны некоторые числа и некоторые оценки варианта использования.
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;
}
Надеюсь, это даст вам лучшее представление о том, как эти вещи работают.
Потоки 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 лучше.
См. здесь , чтобы узнать о лучших способах расширения IOStreams. (Немного устаревший и адаптированный для VC 6, поэтому вам придется отнестись к нему с недоверием)
Дело в том, что для того, чтобы заставить работать функторы (и endl, который выводит "\ n" и сбрасывает, является functor) вам необходимо реализовать полный интерфейс ostream.
Проблема в том, что 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
.
достичь того, чего пытаешься достичь, применяя технику, которую используешь.