Здравствуйте, Elich, Вы писали:
А>>Поповоду макросов, как передать в макросу аргумент с запятыми?
E>[code] E>#define COMMA , E>#define TEST(a, c) a = c
ИМХО, проще добавить лишнюю пару скобок.
#define MACRO(x) x
int main() {
int a = MACRO(5);
int b = MACRO((std::min(7,8)));
};
E>>[code] E>>#define COMMA , E>>#define TEST(a, c) a = c
ГА>ИМХО, проще добавить лишнюю пару скобок.
Честно говоря, не знал, что в списке параметров макроса можно использовать скобки.
Согласен, в приведенном мной примере действительно проще и ощутимо нагляднее.
То же самое и в других случаях, когда сами скобки будут корректны в выражении после подстановки.
Дополнительный макрос для запятой может помочь в тех ситуациях, когда скобки в выражении после подстановки не будут допустимыми.
Например:
#define MACRO(x) x
MACRO((std::vector<std::string, std::allocator<std::string> >)) var; // ошибка
Манипуляторы потоков
От:
Аноним
Дата:
04.10.05 16:56
Оценка:
Проблема заключается в том что надо написать довольно много манипуляторов с аргументами, как можно это сделать с меньшими усилиями?
Самый короткий способ который мне удолось придумать выглядит примерно так:
Здравствуйте, Аноним, Вы писали:
А>Проблема заключается в том что надо написать довольно много манипуляторов с аргументами, как можно это сделать с меньшими усилиями?
class MyManipulatorWith4Arguments
{
public:
MyManipulatorWith4Arguments(T1 a1, T2 a2, T3 a3, T4 a4)
: a1_(a1), a2_(a2), a3_(a3), a4_(a4)
{}
friend std::ostream& operator<<(std::ostream& stream, const MyManipulatorWith4Arguments& manip)
{
// do something useful with stream and manip.a1_–a4_
}
};
Вовсе не вижу причин обязательно реализовывать манипулятор через вывод в поток функции от потока…
Здравствуйте, Аноним, Вы писали:
А>Проблема заключается в том что надо написать довольно много манипуляторов с аргументами, как можно это сделать с меньшими усилиями?
Можно писать объекты-манипуляторы, унаследованные от базового
Причём порождать классы манипуляторов с помощью макросов.
А можно сделать вот так:
template<class F> // F - унарный функтор от потокаclass func_manip_t // специальная обёртка, чтобы обозначить, что этот функтор - манипулятор
{
F f_;
public:
manip_t(F f) : f_(f) {}
friend std::ostream& std::operator<<(std::ostream& ost, const a_manip& m) { f_(ost); return ost; }
friend std::istream& std::operator>>(std::istream& ist, const a_manip& m) { f_(ist); return ist; }
};
template<class F>
func_manip_t<F> fmanip(F f) { return func_manip_t<F>(f); }
.....
void doit(std::ostream&, int t1=0, int t2=0);
void hello(const char*, std::ostream&);
void byebye(std::ostream&, const char*);
void jabberwacky(int x, int y, int z, int t, std::ostream&);
.....
// если нельзя просто записать cout << doit, всегда можно завернуть её в fmanip
std::cout << fmanip(doit);
// связывать можно любым подходящим способом
std::cout << fmanip(boost::bind(hello,"world"));
std::cout << fmanip(std::bind1st(std::ptr_fun(hello),"world"));
// если поток - не последний аргумент, то связываем соответственно
std::cout << fmanip(std::bind2nd(std::ptr_fun(byebye),"baby"));
// если много аргументов - то boost::bind или boost::lambda нас спасут
std::cout << fmanip(boost::bind(jabberwacky,1,2,3,4));
// наконец, можно связать заранее
boost::function<void(std::ostream&)> f = boost::bind(jabberwacky,1,2,3,4);
std::cout << fmanip(f);
.....
Перекуём баги на фичи!
Re[2]: Манипуляторы потоков
От:
Аноним
Дата:
05.10.05 04:31
Оценка:
C>Вовсе не вижу причин обязательно реализовывать манипулятор через вывод в поток функции от потока…
Смысл в том что бы не трогать класс потока. Вовторых, черезмерная перегрузка оператора вывода может вызвать ряд проблем.
К>.....
К>void doit(std::ostream&, int t1=0, int t2=0);
К>void hello(const char*, std::ostream&);
К>void byebye(std::ostream&, const char*);
К>void jabberwacky(int x, int y, int z, int t, std::ostream&);
К>.....
К>// если нельзя просто записать cout << doit, всегда можно завернуть её в fmanip
К>std::cout << fmanip(doit);
К>// связывать можно любым подходящим способом
К>std::cout << fmanip(boost::bind(hello,"world"));
К>std::cout << fmanip(std::bind1st(std::ptr_fun(hello),"world"));
К>// если поток - не последний аргумент, то связываем соответственно
К>std::cout << fmanip(std::bind2nd(std::ptr_fun(byebye),"baby"));
К>// если много аргументов - то boost::bind или boost::lambda нас спасут
К>std::cout << fmanip(boost::bind(jabberwacky,1,2,3,4));
К>// наконец, можно связать заранее
К>boost::function<void(std::ostream&)> f = boost::bind(jabberwacky,1,2,3,4);
К>std::cout << fmanip(f);
К>.....
К>
Спасибо, довольно интересно, но не подходит, виртуальный базовый класс не подходит потому что все эти функции дожны быть встроены. Вариант с fmanip тоже не катит, поскольку в результате это должно выглядеть несколько иначе:
Здравствуйте, Аноним, Вы писали:
C>>Вовсе не вижу причин обязательно реализовывать манипулятор через вывод в поток функции от потока…
А>Смысл в том, чтобы не трогать класс потока.
Так а он и не трогается…
А>Во-вторых, чрезмерная перегрузка оператора вывода может вызвать ряд проблем.
А поподробнее о проблемах? Проблемы будут, если забыть сделать конструктор манипулятора явным (explicit).
А>Поповоду макросов, как передать в макросу аргумент с запятыми?
#define COMMA ,
#define TEST(a, c) a = c
int main()
{
int a = 10, b = 20, c = 30;
TEST(a COMMA b, c);
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
return 0;
}
Здравствуйте, Аноним, Вы писали:
А>Спасибо, довольно интересно, но не подходит, виртуальный базовый класс не подходит потому что все эти функции дожны быть встроены. Вариант с fmanip тоже не катит, поскольку в результате это должно выглядеть несколько иначе:
Ты уверен, что инлайновость критична? Это результат профилирования, горького опыта или предубеждение?
Учти, что boost::bind тоже вызывает функцию косвенно.
Перекуём баги на фичи!
Re[4]: Манипуляторы потоков
От:
Аноним
Дата:
05.10.05 14:18
Оценка:
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Аноним, Вы писали:
А>>Спасибо, довольно интересно, но не подходит, виртуальный базовый класс не подходит потому что все эти функции дожны быть встроены. Вариант с fmanip тоже не катит, поскольку в результате это должно выглядеть несколько иначе: К>
К>Ты уверен, что инлайновость критична? Это результат профилирования, горького опыта или предубеждение? К>Учти, что boost::bind тоже вызывает функцию косвенно.
Да, уверен, что является результатом предубеждения.
Всем спасибо, все понял, все сделал. Очень признателен.