-1

I've tried my best to find an answer to my question, and while I did find some good resources, I still cannot wrap my head around this. First of all, I am not very familiar with the newish C++11 standard. Variadic templates and all that stuff, gets my head hurting real fast. Nor did I play much with the STL of C++, so even vectors are a bit of a left-field for me, and I like Python a lot, and most my experience is there. But recently surfing the web, I was curious about constructing my own MIDI player/creator and I found a nice resource. I will post it in the comments if context is required and asked for, but what I am having trouble understanding is this:

typedef unsigned char byte;

/* First define a custom wrapper over std::vector<byte>
 * so we can quickly push_back multiple bytes with a single call.
 */
class MIDIvec: public std::vector<byte>
{
public:
    // Methods for appending raw data into the vector:
    template<typename... Args>
    void AddBytes(byte data, Args...args)
    {
        push_back(data);
        AddBytes(args...);
    }
    template<typename... Args>
    void AddBytes(const char* s, Args...args)
    {
        insert(end(), s, s + std::strlen(s));
        AddBytes(args...);
    }
    void AddBytes() { }
};

Starting from the very top, I have no clue what class MIDIvec: public std::vector does. I understand that-- actually, I am not even sure about that. I understand what the class is doing, but I do not understand the logic behind it.

First of all, it appears that wrapping vector MIDIvec allows MIDIvec to call vector member functions, is that correct? And second, I do not understand these templates- I do understand how they work, and I should really google this, and I did, but the explanation was really hard for me to understand in the sense of the code sample I provided.

Also, is Variadic Templates responsible for defining AddBytes three times? I am assuming based on the arguments, a different version of the function will be called that matches the arguments provided?

I feel like I am punching way above my weight, and that I am looking at the work of a master who took a lot of shortcuts in writing this code, even though he apparently did all the design and coding in one night, but I feel that my own understanding of programming will improve tremendously if I was to be helped to understand what was going on here.

1 Answers1

0

Class MIDIvec is derived from vector, it's bad design in general and composition will be better.

AddBytes has 3 overloads, one for byte and args pack, one for const char* and args pack and one for empty pack (the end of recursion).

So, let's call it.

AddBytes(byte(1), "abc", byte(2));

Here will be called one with byte first arg, since pack is byte, const char*, byte, then from function will be called one with const char*, since now pack is const char*, byte, then will be called one with byte, since pack is byte and then will be called one without args, since pack is empty.

ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • Oh, I totally get it now. I completely forgot how class derivation works, it all makes sense now. And I knew back when I was picking up C++ that I should've paid more attention to overloads- and I sort of did, but I didn't really imagine them to be used with variadic templates. Thanks a bunch for explaining! Had I used my brain I think I would've figured it out too! I have just one last question- where exactly does the data get pushed back in the first AddByte call? Is MIDIvec the vector in this case? – SaintOfWar Jan 15 '16 at 10:50
  • @SaintOfWar yes, `MIDIvec` is an `std::vector`. – ForEveR Jan 15 '16 at 10:58
  • Thanks! I think I got it now. – SaintOfWar Jan 15 '16 at 11:04