#include <iostream>
#include <list>
#include <utility>

using namespace std;

typedef list<pair<string, string> > KeyVal;
struct Header { string name; string value; Header(string name, string value) : name(name), value(value) {}; };
struct Param { string name; string value; Param(string name, string value) : name(name), value(value) {}; };

/* Something that contains headers */
template<typename T> class WithHeaders {
  KeyVal headers;
public:
  virtual T &operator <<(const Header &h) {
    headers.push_back(pair<string, string>(h.name, h.value));
    return static_cast<T&> (*this);
  }
};

/* Something that contains query params */
template<class T> class WithQuery {
    KeyVal query_params;

public:
    virtual T &operator <<(const Param &q) {
      query_params.push_back(pair<string, string>(q.name, q.value));
      return static_cast<T&> (*this);
    }

    const KeyVal &get_query() const {return query_params;}
};

/* Http Request has both headers and query parameters */
class Request: public WithQuery<Request>, public WithHeaders<Request> {
public:
	using WithHeaders<Request>::operator<<;
	using WithQuery<Request>::operator<<;
};

int main() {
	Request rq;
	rq << Header("a", "b");
	return 0;
}