tags:

views:

72

answers:

3

Hello,

I'm trying to determine if the following scenario is appropriate for a template, and if so how it would be done.

I have a base class, event_base. It is inherited by specific types of events.

class event_base_c {
    //... members common to all events ...

    // serialize the class for transmision
    virtual std::string    serialize(void);
};


class event_motion_c : public event_base_c {
  //... members for a motion event ...

  // serialize the class for transmission
  virtual std::string    serialize(void);
};


class event_alarm_c : public event_base_c {
  //... members for a motion event ...

  // serialize the class for transmission
  virtual std::string    serialize(void);
};

Events get serialized and sent from one various process to an event logger, which recreates the event object from the serialized data.

My question is with regards to the processes that are sending the events. We cannot include a 'send()' method in the event class. I have been told that I need to create an event_sender object that knows how to send the serialized event. So the code from one process might be:

if (motion_detected on sensor1) {
    event_motion_c    Event(sensor1, x, y, z);
    event_sender      EventSender;

    EventSender.report(Event.serialize());
}

While some other process might report an alarm using similar code such as:

if (alarm) {
    event_alarm_c     Event(alarm_id, alarm_type);
    event_sender      EventSender;

    EventSender.report(Event.serialize());
}

This feels like a template candidate to me, but what stops/confuses me is that the constructor for the different event classes have different number of parameters. I do not know if templates support something like that, and if they do, I don't know the syntax for doing so.

I could easily define this as a macro such as:

#define SEND_EVENT(evt_class, args...)          \
    {                                           \
        evt_class       Event(#args);           \
        event_sender    EventSender;            \
                                                \
        EventSender.report(Event.serialize());  \
    }

Then the coder would simply use:

SEND_EVENT(event_motion_c, sensor1, x, y, z);

and

SEND_EVENT(event_alarm_c, alarm_type);

But I am hesitant to make a macro for this.

Do templates support variable numbers of parameters? And if so, how is that done?

+1  A: 

no.

In C++ variadic templates are not supported. But you can easily overcome that by giving template defaults:

template<class I, class J = void>
struct S;

template<class, class> struct S {}; // two parameter
template<class I> struct S<I> {}; //  "single" parameter, second parameter is void

S<int, int>; // two parameter instance
S<int>; // "single" parameter instance

the default does not have to be void type, it can be anything.

sometimes the style may become too messy (if you have lots of defaults), then you can use boost preprocessor, namely:

http://www.boost.org/doc/libs/1_43_0/libs/preprocessor/doc/ref/enum_params_with_a_default.html

http://www.boost.org/doc/libs/1_43_0/libs/preprocessor/doc/ref/enum_params.html

http://www.boost.org/doc/libs/1_43_0/libs/preprocessor/doc/ref/enum_binary_params.html

aaa
+1  A: 

Variadic templates are an in-progress C++0x feature. You've been able to at least start using them as of GCC 4.3. I don't pay much attention to Microsoft.

Jon Purdy
+1  A: 

C++ does not support variadic templates, but C++0x will, and some compilers already have support for this (including G++ with the --std=c++0x flag). Wikipedia has examples of how to use this feature.

bdonlan