I want to write an unmarshaller to extract arguments stored in a msgpack array for individual arguments to a call of sigc::signal::emit(...)
. I tried this:
template<class... T> class MsgpackAdapter: public MsgpackAdapterBase {
public:
MsgpackAdapter (sigc::signal<void, T...> &sig)
: MsgpackAdapterBase (), signal_ (sig)
{}
protected:
virtual void do_emit (const msgpack::object_array &mp_args) override;
private:
sigc::signal<void, T...> signal_;
};
template<class T1>
void MsgpackAdapter<T1>::do_emit (const msgpack::object_array &mp_args)
{
T1 a1;
mp_args.ptr[0].convert (a1);
signal_.emit (a1);
}
template<class T1, class T2>
void MsgpackAdapter<T1, T2>::do_emit (const msgpack::object_array &mp_args)
{
T1 a1;
T2 a2;
mp_args.ptr[0].convert (a1);
mp_args.ptr[1].convert (a2);
signal_.emit (a1, a2);
}
and so on for up to 4 arguments. But I get this error message (from vim-youcompleteme using clang 3.9):
'MsgpackAdapter<T1>::' for declaration does not refer into a class, class template or class template partial specialization
It seems I can make partial specializations of the entire class:
template<class T1> class MsgpackAdapter<T1>: public MsgpackAdapterBase { ... };
but I'd rather be able to specialize just the emit
method to reduce the amount of copy & paste code. Have I missed something obvious? I think the main difficulty is that do_emit
doesn't take templatized arguments.
Another curiosity is that if I try to do it without the variadic template, and use:
template<class T1> class MsgpackAdapter: public MsgpackAdapterBase { ... };
template<class T1, class T2> class MsgpackAdapter: public MsgpackAdapterBase { ... };
I get an error that the second class definition clashes with the first. That's understandable, but I wonder how sigc managed a similar thing without variadic templates.