У меня есть сильно используемый (и оптимизированный) тип, который хранит ссылки на большее количество данных с помощью небольших целых чисел. Для отладки я хотел бы написать operator<<
который запрашивает дополнительные данные для создания лучшего отладочного вывода. Как передать эту дополнительную контекстную информацию operator<<
?
Вот пример:
/** Rich information */
struct Item {
short id;
std::string name;
...
};
struct Database {
std::map<short,Item> items;
...
};
/** Very optimized light-weight data type */
struct Foo {
short a, b; // actually references to Item
};
/** for debugging etc. */
void print(std::ostream& os, const Foo& f, const Database& db) {
os << "(" << db.items[f.a].name << "," << db.items[f.b].name << ")";
}
Database db;
items[0] = {0, "item0"};
items[1] = {1, "item1"};
Foo foo{0,1};
std::cout << "foo="; print(std::cout, foo, db); std::cout << std::endl; // ugly
std::cout << "foo=" << foo << std::endl; // How to get db ???
Вы можете создать свой собственный print_database
манипулятора, который перегружает operator <<
:
class print_database
{
public:
print_database(const Foo& foo, const Database& db)
: foo(foo), db(db)
{ }
template<class cT>
friend std::basic_ostream<cT>& operator<<(std::basic_ostream<cT>& os,
const print_database& manip)
{
manip.print(os);
return os;
}
private:
Foo foo;
Database db;
template<class cT>
void print(std::basic_ostream<cT>& os) const
{
os << "(" << db.items[foo.a].name << "," << db.items[foo.b].name << ")";
}
};
Тогда ваша функция print
может быть реализована как:
print_database print(const Foo& foo, const Database& db)
{
return print_database(foo, db);
}
Итак, теперь вы можете назвать это как:
std::cout << print(foo, db) << std::endl;
std::basic_ostream<cT>
вместо std::ostream
?
std::ostream
.
Я не знаю, считаете ли вы его более или менее уродливым, но, возможно, что-то вроде:
debug_printer dp { db };
std::cout << dp(foo) << std::endl;
Где op<<
- перегрузка для отладочного принтера; или op()
может возвращать std::string
.
dp(foo)
?
std::string
, либо возвращает прокси-сервер, который фактически выполняет печать (имеется в виду, что это будет фактически какой-то генератор), либо устанавливает какое-то внутреннее состояние в принтере на «печать с едой».
Item
вstd::map<short, Item>
являетсяItemData
?Item
поshort
изDatabase
? Я действительно не понимаю, почему речь идет о потоках.