5

我想换行std::cout进行格式化,如下所示:

mycout([what type?] x, [optional args]) {
    ... // do some formatting on x first
    std::cout << x;
}

并且仍然能够使用富有表现力的语法,例如

mycout("test" << i << endl << somevar, indent)

而不是被迫变得更冗长

mycout(std::stringstream("test") << i ...)

我该如何实施?做什么类型的x

编辑:增加了对可选参数的考虑

4

4 回答 4

5

这个怎么样:

struct MyCout {};

extern MyCout myCout;

template <typename T>
MyCout& operator<< (MyCout &s, const T &x) {
  //format x as you please
  std::cout << x;
  return s;
}

并放入MyCout myCout;任何一个 .cpp 文件中。

然后你可以myCout像这样使用:

myCout << "test" << x << std::endl;

operator<<它会调用可以进行格式化的模板。

当然,如果您愿意,您还可以为特定类型的特殊格式提供运算符的重载。

编辑

显然(感谢@soon),为了使标准操纵器工作,需要更多的重载:

MyCout& operator<< (MyCout &s, std::ostream& (*f)(std::ostream &)) {
  f(std::cout);
  return s;
}

MyCout& operator<< (MyCout &s, std::ostream& (*f)(std::ios &)) {
  f(std::cout);
  return s;
}

MyCout& operator<< (MyCout &s, std::ostream& (*f)(std::ios_base &)) {
  f(std::cout);
  return s;
}

编辑 2

我可能稍微误解了您的原始要求。这个怎么样(加上与上面相同的操纵器重载):

struct MyCout
{
  std::stringstream s;

  template <typename T>
  MyCout& operator << (const T &x) {
    s << x;
    return *this;
  }

  ~MyCout() {
    somehow_format(s);
    std::cout << s.str();
  }
};

int main() {
  double y = 1.5;
  MyCout() << "test" << y;
}
于 2013-05-08T15:15:36.657 回答
4

这很容易通过可变模板参数实现:

template <class T>
void print(T t)
{
    std::cout << t;
}

template <class T, class... Args>
void print(T t, Args... args)
{
    std::cout << t << std::endl;
    print(args...);
}

int main()
{
    std::cout << std::boolalpha;
    print(3, 's', true, false);
}

输出:

3
s
true
false

现场演示

于 2013-05-08T15:10:19.193 回答
1

答案的变体:

#include <iostream>

using namespace std;

class MyCout 
{
public:
  MyCout& operator()(bool indent) { 
    if ( indent ) cout << '\t'; 
    return *this;
  }

  template<class T>
  MyCout& operator<<(T t) {
    cout << t;
    return *this;
  }

  MyCout& operator<<(ostream& (*f)(ostream& o)) {
    cout << f;
    return *this;
  };
};

int main()
{
  MyCout mycout;
  int x = 10;
  mycout(true)<< "test" << 2 << x << endl ;
}
于 2013-05-08T15:55:06.840 回答
0

您可以使用这种类:

#include <iostream>

using namespace std;

class CustomOut
{
public:

    template<class T>
    CustomOut& operator<<(const T& obj)
    {
        cout << " my-cout " << obj;
        return *this;
    }

};

int main()
{
    CustomOut mycout;
    mycout << "test" << 4 << "\n" << 3.4;
}

您需要更多代码才能使用 std::endl 和其他仿函数,所以我在这里使用了简单的 \n 代替。

于 2013-05-08T15:19:31.777 回答