2

This may be a very basic question but while digging through STL reference I can't find anything suitable. As an example

std::ostringstream oss;
oss << "One hundred and one: " << 101;

would result in One hundred and one: 101 stored in oss, means the numeric value 101 is converted to text. What I'm looking for is a stream object that keeps the numeric value so that something like:

numstream nums;
nums << 10 << 0 << 15;

would result in a byte or string buffer containing not a textual representation of 10, 0 and 15 but just these three numbers.

Any idea what could be used for this?

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
Elmi
  • 5,899
  • 15
  • 72
  • 143

2 Answers2

1

A buffer containing a sequence of integers is what std::vector<int> controls.

You can override the global operator << to append any type T to any container type C for which such an operation is meaningful:

#include <vector>
#include <iostream>

std::vector<int> & operator<<(std::vector<int> & vi, int i)
{
    vi.push_back(i);
    return vi;
}

int main()
{
    std::vector<int> vi;
    vi << 1 << 2 << 3;
    for(auto i : vi) {
        std::cout << i << std::endl;
    }
    return 0;
}

However, if all you want to achieve is an abbreviation of, e.g.

si.push_back(i);

for some integer sequence si and int i, and to be able to shorten, e.g.

si.push_back(i);
si.push_back(j);
si.push_back(k);

to:

si << i << j << k;

remember that the brevity you gain comes at the cost of making otherwise skilled readers research what your abbreviations are - and how safe they are.

I suggest that shortening si.push_back(i) to si << i is not worthwhile and that if you want to get tiresomely long sequences of push_back(n) onto one line then it would be sufficient and less eccentric to define a type-safe variadic function template for the purpose, e.g.

void push_back(std::vector<int> & vi){}

template<typename ...Ts>
void push_back(std::vector<int> & vi, int i, Ts... ts)
{
    vi.push_back(i);
    if (sizeof...(Ts)) {
        push_back(vi,ts...);
    }
}

With which you would write, e.g.

push_back(si,i,j,k);

rather than:

si << i << j << k;
Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
0

With this semantic (stream insertion): no there isn't.

From your example it looks like you want to fill a vector of integers with integers.

You will need a functor (ostream manipulator) which would translate the ostream-like semantics into vector-element-addition.

Something along the lines of:

struct functor {
   functor(std::vector<int>& viref):
      myVector(viref)
   {}
   // this operator overload translates stream-insert operator
   // into vector element addition
   functor& operator<<(const int i) {
      myVector.push_back(i);
      return *this;
   }
   std::vector<int>& myVector;
};

int main() {
   std::vector<int>   vi;
   functor            f( vi );

   f << 1 << 2 << 3;
}

Alternatively, you could always write your own streambuffer class (http://www.cplusplus.com/reference/streambuf/streambuf/) but I doubt that that will go down very well because the whole string/stream buf mechanism really is meant to be dealing with single characters being inserted/removed.

emvee
  • 4,371
  • 23
  • 23