gpt4 book ai didi

c++ - 部分特化可变参数模板类的方法

转载 作者:行者123 更新时间:2023-11-27 23:55:28 26 4
gpt4 key购买 nike

我想编写一个解码器来提取存储在 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 个参数。但我收到此错误消息(来自使用 clang 3.9 的 vim-youcompleteme):

'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 如何在没有可变参数模板的情况下管理类似的事情。

最佳答案

我一直觉得特化一个成员函数最容易维护的方法是遵从一个特化的函数对象:

#include <iostream>

struct object_array
{
};


template<class...Ts>
struct implement_do_emit
{
template<class This>
void operator ()(This *that, const object_array& arg) const;
};


template<class... Ts>
struct MsgpackAdapter
{
friend class implement_do_emit<Ts...>;

virtual void do_emit(const object_array& mp_args)
{
auto impl = implement_do_emit<Ts...>();
impl(this, mp_args);
}

};

template<class T>
struct implement_do_emit<T>
{
template<class This>
void operator ()(This *that, const object_array& arg) const
{
std::cout << "one type version\n";
}
};

template<class T1, class T2>
struct implement_do_emit<T1, T2>
{
template<class This>
void operator ()(This *that, const object_array& arg) const
{
std::cout << "two type version\n";
}
};


int main()
{
MsgpackAdapter<int> pi {};
pi.do_emit(object_array());

MsgpackAdapter<int, int> pii {};
pii.do_emit(object_array());
}

关于c++ - 部分特化可变参数模板类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42934044/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com