Как создать псевдоним для нескольких потоковых операций?

Есть ли способ создать сокращенный псевдоним для следующей строки в С++ 98?

std::precision(3) << std::fixed

А затем используйте псевдоним следующим образом:

std::cout << alias << 3.1415926 << std::endl;

person BigBrownBear00    schedule 03.10.2016    source источник
comment
Что такое С++ 99?   -  person Lightness Races in Orbit    schedule 03.10.2016
comment
@LightnessRacesinOrbit Новый предстоящий стандарт 2099 года.   -  person Hatted Rooster    schedule 03.10.2016
comment
Возможно, просто используйте #define.   -  person Hatted Rooster    schedule 03.10.2016
comment
Или может лямбда? Но я не уверен, что он доступен в C++99.   -  person DeiDei    schedule 03.10.2016
comment
Нельзя использовать auto или lambda. c99: en.wikipedia.org/wiki/C99   -  person BigBrownBear00    schedule 03.10.2016
comment
Этот стандарт не имеет ничего общего с C++.   -  person Hatted Rooster    schedule 03.10.2016
comment
@GillBates Как будто это будет закончено до начала века.   -  person Yakk - Adam Nevraumont    schedule 03.10.2016
comment
@GillBates: лол   -  person Lightness Races in Orbit    schedule 03.10.2016
comment
@ user1054424: Приятель, это стандарт C. Это другой язык... Нет C++99.   -  person Lightness Races in Orbit    schedule 03.10.2016
comment
извините - я имел в виду С++ 98. Исправил в исходном посте   -  person BigBrownBear00    schedule 03.10.2016


Ответы (1)


Стандартным способом, вероятно, было бы создание собственного манипулятора:

std::ios_base& alias(std::ios_base& str) {
    str.precision(3);
    return std::fixed(str);
}

Затем:

std::cout << alias << 3.16464;

См. перегрузку (9) для operator<<:

basic_ostream& operator<<(std::ios_base& (*func)(std::ios_base&))

Если вы хотите указать аргументы, вам нужна промежуточная структура:

struct alias_t {
    int n;
};

alias_t setalias(int n) { return {n}; }

template <class CharT, class Traits>
std::basic_ostream<CharT, Traits>& 
operator<<(std::basic_ostream<CharT, Traits>& out, const alias_t& alias) {
    return out << std::fixed << std::setprecision(alias.n);
}

// Or if you do not care about genericity:
std::ostream& operator<<(std::ostream& out, const alias_t& alias) {
    return out << std::fixed << std::setprecision(alias.n);
}

Затем:

std::cout << setalias(6) << 3.16464;
person Holt    schedule 03.10.2016
comment
Красивый. Благодарю вас! - person BigBrownBear00; 03.10.2016
comment
Есть ли причина предпочесть эти две строки просто return str << std::setprecision(3) << std::fixed;? Я имею в виду функционально, а не стилистически. - person TartanLlama; 03.10.2016
comment
@TartanLlama str здесь не поток, поэтому я думаю, что это не сработает. - person Holt; 03.10.2016
comment
@ Холт А, верно. Я думаю, это сработало бы, если бы вместо этого функция использовала std::ostream&, но это не было бы таким общим? - person TartanLlama; 03.10.2016
comment
@TartanLlama Это работает только из-за упомянутой мной перегрузки, но вы можете добиться аналогичного поведения, создав собственный класс с одним экземпляром и перегрузив operator << для ostream. - person Holt; 03.10.2016
comment
std::ostream уже имеет соответствующую перегрузку. Но неважно, твой ответ все равно лучше :) - person TartanLlama; 03.10.2016
comment
@Holt, есть ли способ заставить alias принимать аргумент, чтобы я мог установить точность в качестве аргумента функции? std::cout << alias(2) << 3.16464 ? - person BigBrownBear00; 03.10.2016
comment
@TartanLlama Да, ты прав - я всегда забывал об этом. Единственное преимущество std::ios_base в этом случае заключается в том, что он более общий (вы можете сделать свой немного более общим, но для этого потребуется шаблон). Я также предпочитаю std::ios_base, потому что он используется std::fixed и ему подобным манипулятором. - person Holt; 03.10.2016
comment
@ BigBrownBear00 Да, но это может быть немного сложнее, я обновлю свой ответ. - person Holt; 03.10.2016