1

I need a buffer class. I found "std::vector" pretty useful, but I don't like, for example, to do this:

typedef std::vector<char> Buffer;
Buffer buff1;
Buffer buff2;
...
buff1.insert(buff1.end(), buff2.begin(), buff2.end())

Each time I want to append... I would like to have some concat method, something like:

buff1.append(buff2)

or an operator+= or something.

Now, I've tried to add this method:

void append(dataStructures::Buffer& self, const dataStructures::Buffer& other)
{
    self.insert(self.end(), other.begin(), other.end());
}

and call it simply by: buff1.append(buff2) but it won't compile, for the reason:std::vector<byte, std::allocator<byte>>" has no member "append". That is right. I've also tried to get "self" as a pointer, with no success. It does work when adding operator<< to the std::ostream, so I really expected it to work, but I was wrong.

I can, of course, create a Buffer using the inheritance mechanism, but std containers have no virtual Dtor, so that might be a bad idea (Although I'm not adding any member variables... still a bad idea).

Is there any way to do what I want? I know it's only a matter of readability, but it is important for me. I'm wondering if there is a simple solution, or my only option is to implement a proxy class or a whole new Buffer class (I've tried to use boost's Buffer, but it doesn't allocate memory, as much as I understood).

Thank you very much.

  • [Yakk](http://stackoverflow.com/users/1774667/yakk) [to the rescue](http://stackoverflow.com/a/16845998/420683)! Although.. umm ... I don't know if I should recommend that approach. – dyp Aug 06 '13 at 18:41
  • I saw this when trying to google for a solution. The cool thing is that it's so complicated yet working. Every other aspect about this code is just so bad... I still can't understand it. I was looking for an elegant piece of code, because my intention is to make my code as readable as possible (beside the critical parts that I really need to run fast). But thank you anyway, I think I can learn from this code :) – Asaf Nudler Aug 06 '13 at 21:51

6 Answers6

6

You cannot add new methods to a class without deriving a new class from it. You were on the right track by defining a standalone helper function, but you were calling it the wrong way:

//buff1.append(buff2) 
append(buff1, buff2) ;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
2

try append(buff1, buff2)

you cannot declare a new function of the class but you can just make a function that wraps the behavior you want.

Logan Murphy
  • 6,120
  • 3
  • 24
  • 42
1

I'm assuming here that you don't want to just use append(buff1, buff2). What you are doing there is possible in the the language D, but not in C++. If you really want infix notation in C++, i.e., that both operands are on different sides of your function name, your only option is to overload an operator, e.g.:

void operator+=(dataStructures::Buffer& self, const dataStructures::Buffer& other)
{
    self.insert(self.end(), other.begin(), other.end());
}

Which you can then use as buff1 += buff2;

ltjax
  • 15,837
  • 3
  • 39
  • 62
0

You're going to have to create a whole new class, but use composition instead of inheritance:

class Buffer {
public:
    //...Constructor, Destructor, Assigment, Compound Assignment, Append methods, etc.
protected:
private:
    std::vector<char> _data;
};
Casey
  • 10,297
  • 11
  • 59
  • 88
0

It is not working because, you append function work like :

 append( buf1, buf2 );

Think about wrapping instead of inheritance.

So :

class Buffer
{
public:
    // ...

    void append( const Buffer& iOther );

private:
    std::vector<char> m_Data;
};
Pierre Fourgeaud
  • 14,290
  • 1
  • 38
  • 62
0

C++ has a way to define global operators such that you can add a += operator or a << to a std::vector if you wanted to. Here's an example:

#include <vector>
#include <stdlib.h>
#include <stdio.h>
template<typename T>
void operator+=(std::vector<T>& a, const std::vector<T>& b)
{
     a.insert(a.end(), b.begin(), b.end());
}

int main()
{
size_t i;
std::vector<int> list1;
std::vector<int> list2;
for(i = 0; i < 3; ++i)
{
    list1.push_back(rand());
}

for(i = 0; i < 3; ++i)
{
    list2.push_back(rand());
}

for(i = 0; i < list1.size(); ++i)
{
    printf("%d ", list1[i]);
}

printf("\n");
list1 += list2;
for(i = 0; i < list1.size(); ++i)
{
    printf("%d ", list1[i]);
}   
}

However it's probably better to make a helper function as it is probably a lot clearer what you want to do with it, maybe += doesn't mean the exact same thing in everyone's mind

Radu Chivu
  • 1,057
  • 7
  • 17