Ну вот, думаю, это работает. Вы должны заметить, что делать это может быть плохой идеей, потому что этот код в лучшем случае фанк, прямо ошибочным или в худшем случае некорректным. Я не проверял и не проверял это глубоко, но я знаю, что он компилируется и работает в моей системе (Windows 7 / MSVC10). Если бы я увидел что-то подобное в рабочем коде, я бы, вероятно, посчитал это хаком, и в противном случае мне бы пришлось убедиться в этом.
Наслаждайтесь.
#include <cstdlib>
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
namespace Errors
{
class errstream
{
public:
errstream(const std::string& filename, int lineno) : file_(filename), line_(lineno) {};
std::string dump() const;
errstream& operator<<(const std::string& msg)
{
cout << msg << "\t[" << file_ << ":" << line_ << "]";
return * this;
}
private:
std::string file_;
int line_;
};
};
#define err errstream(__FILE__, __LINE__)
int main()
{
Errors::err << "Oh no. That was a bad thing.";
}
Вывод (для меня):
О нет. Это было плохо. [Main.cpp: 30]
РЕДАКТИРОВАТЬ: КРУГЛЫЙ 2
В комментариях ниже было указано новое требование. ОП хотел иметь возможность сделать что-то вроде этого:
Errors::err << "File Not Found '" << file << "' What A Bummer. :(";
... и иметь вывод:
Файл не найден! 'foo.txt' Какой облом. :( [файл: nnn]
Мой исходный код не будет выводить этот вывод, потому что он не может обрабатывать несколько потоковых вставок только с одним добавленным токеном для местоположения. Вместо этого вывод становится большим беспорядком:
Файл не найден! '[main.cpp: 61] foo.txt [main.cpp: 61]' Что за
облом. :( [main.cpp: 61]
Этого можно добиться, если errstream
вывести свое содержимое в cout
при вызове деструктора, а не при вызове оператора вставки потока. Оператор вставки потока, в свою очередь, somply собирает токены, которые будут выгружены в cout перед строкой местоположения. Новый код:
#include <cstdlib>
#include <sstream>
#include <string>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
namespace Errors
{
class errstream
{
public:
errstream(const std::string& filename, int lineno) : file_(filename), line_(lineno) {};
~errstream()
{
std::copy(tokens_.begin(), tokens_.end(), ostream_iterator<string>(cout));
cout << "\t[" << file_ << ":" << line_ << "]\n";
}
errstream& operator<<(const std::string& msg)
{
tokens_.push_back(msg);
return *this;
}
private:
typedef std::vector<std::string> Tokens;
Tokens tokens_;
std::string file_;
int line_;
};
};
#define err errstream(__FILE__, __LINE__)
int main()
{
Errors::err << "Oh no. That was a bad thing.";
string file = "foo.txt";
Errors::err << "File not found! '" << file << "' What a bummer. :(";
}
Вывод теперь:
О нет. Это было плохо. [main.cpp: 38]
Файл не найден! 'foo.txt' Какой облом. :( [main.cpp: 41]