【发布时间】:2017-08-13 12:40:32
【问题描述】:
我想编写一个解组器来提取存储在 msgpack 数组中的参数,用于调用 sigc::signal::emit(...) 的单个参数。我试过这个:
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);
}
以此类推,最多 4 个参数。但我收到此错误消息(来自 vim-youcompleteme 使用 clang 3.9):
'MsgpackAdapter<T1>::' for declaration does not refer into a class, class template or class template partial specialization
看来我可以对整个班级进行部分专业化:
template<class T1> class MsgpackAdapter<T1>: public MsgpackAdapterBase { ... };
但我宁愿只专门化 emit 方法来减少复制和粘贴代码的数量。我错过了什么明显的东西吗?我认为主要的困难是do_emit 不接受模板化参数。
另一个好奇是,如果我尝试在没有可变参数模板的情况下这样做,并使用:
template<class T1> class MsgpackAdapter: public MsgpackAdapterBase { ... };
template<class T1, class T2> class MsgpackAdapter: public MsgpackAdapterBase { ... };
我收到第二个类定义与第一个类定义冲突的错误。这是可以理解的,但我想知道 sigc 如何在没有可变参数模板的情况下管理类似的事情。
【问题讨论】:
-
使用由 doEmit 调用的辅助模板类,并对其进行专门化
-
如果不专门化整个类,就不能单独专门化一个成员。
-
为什么要写 N 个版本,为什么不写一个呢?在 C++14 中容易,在 C++11 中更难,但总比重复自己要好。我说重复自己很糟糕吗?值得重复。
标签: c++ c++11 variadic-templates unmarshalling template-specialization