如何为cout编写一个允许表达语法的函数包装器?

时间:2013-05-08 15:06:13

标签: c++ wrapper cout

我想将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 个答案:

答案 0 :(得分: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

Live Demo

答案 1 :(得分:3)

这个怎么样:

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;
}

答案 2 :(得分: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而不是。

答案 3 :(得分:0)

答案的变体:

#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 ;
}