Бустер-карусель не лучший выбор для этой проблемы. Используйте «сова-карусель». По вопросам 2 и 3 вы можете узнать больше о «позиции» в css
.
Дополнительная информация по Вопросу 1
Дополнительная информация по Вопросам 2 и 3
.
Можно использовать друга определение, которое определит оператор в окружающем пространстве имен класса и сделает его только видимым к разрешению перегрузки оператора (не вызываемый вручную использование:: оператор <<... синтаксис):
class Logger
{
public:
Logger();
~Logger();
std::ostream* out_stream;
template <typename T>
friend Logger& operator<< (Logger& logger, T thing) {
*logger.out_stream << thing;
return logger;
}
/* special treatment for std::wstring. just overload the operator! No need
* to specialize it. */
friend Logger& operator<< (Logger& logger, const std::wstring & wstr) {
/* do something here */
}
};
Альтернатива, для хранения кода, как это - и просто делает оператор <<, обрабатывает друга по шаблону, Вы добавляете эту строку в свое определение класса:
template <typename T>
friend Logger& operator<< (Logger& logger, T thing);
Для проблемы с манипулятором я просто дам Вам свой код, который я пишу некоторое время назад:
#include <iostream>
#include <cstdlib>
using namespace std;
template<typename Char, typename Traits = char_traits<Char> >
struct logger{
typedef std::basic_ostream<Char, Traits> ostream_type;
typedef ostream_type& (*manip_type)(ostream_type&);
logger(ostream_type& os):os(os){}
logger &operator<<(manip_type pfn) {
if(pfn == static_cast<manip_type>(std::endl)) {
time_t t = time(0);
os << " --- " << ctime(&t) << pfn;
} else
os << pfn;
return *this;
}
template<typename T>
logger &operator<<(T const& t) {
os << t;
return *this;
}
private:
ostream_type & os;
};
namespace { logger<char> clogged(cout); }
int main() { clogged << "something with log functionality" << std::endl; }
};
Обратите внимание, что это - станд.:: шестнадцатеричное число, но не станд.:: iOS:: шестнадцатеричное число. Последний используется в качестве флага манипулятора для setf
функция потоков. Обратите внимание, что для Вашего примера, tho, никакой специальный режим манипуляторов не требуется. Вышеупомянутый специальный режим станд.:: endl только необходим, потому что я действительно передаю время потоком, кроме того, когда станд.:: endl используется.
Никакому объявлению дружбы не было нужно:
class Logger
{
public:
Logger();
~Logger();
template <typename T>
inline Logger& Display(T thing)
{
*out_stream << thing;
return *this;
}
private:
std::ostream* out_stream;
};
template <typename T>
Logger& operator<< (Logger& logger, T thing)
{
return logger.Display(thing);
}
почему бы не это printf путь и использование много метод параметра (с тремя точками...). Это все еще дает Вам большое форматирование питания и не делает его настолько грязным как тогда, когда Вы используете <<.
Например:
Logger("This is my log msg %0X", 45);
Зависните на двух secs и плохо потяните пример кода для Вас.
Править:
void Logger(const char* format, ...)
{
char szMsg[3000];
va_list args;
va_start( args, format );
vsnprintf( szMsg, sizeof(szMsg) - 1, format, args );
va_end(args);
// code to print szMsg to a file or whatever here
}
Если Вы хотите использовать это в качестве класса не одинокая функция, Вы могли бы перегрузить оператор регистратора (), и он будет работать все равно
Используя шаблон правильный способ сделать это, но просто необходимо удостовериться, что шаблон находится в заголовочном файле (logger.h
, или независимо от того, что Вы звонили), не в файле реализации (logger.cpp
). Это будет автоматически работать на любой тип, который имеет operator <<
определенный с std::ostream
. Это будет также автоматически работать с потоковыми объектами манипулятора - это - действительно просто функции, которые берут std::ostream
параметр, и operator <<
просто вызывает функцию на ostream
.
Можно сделать operator <<
друг функция следующим образом:
template <typename T> friend Logger& operator<< (Logger& logger, T thing);
Специализации легки - просто используют шаблонные специализации (снова, в заголовочном файле):
template <typename T>
Logger& operator<< (Logger& logger, T thing) {
*logger.out_stream << thing;
return logger;
}
// Template specialization - the "template <>" part is necessary
template <>
Logger& operator<< (Logger& logger, const wchar_t *wstr)
{
// convert wstr to an ANSI string and log it
}
template <>
Logger& operator<< (Logger& logger, const std::wstring & wstr)
{
// convert wstr to an ANSI string and log it
}