Boost的signals2库为一些扩展功能(通过其参数库)定义了一种传递备用参数的好方法。当其中一个备用参数在我的代码中相当普遍时,我想做一个帮助来进一步简化使用;例如,要指定备用互斥锁类型,我可以这样做:
namespace bs2 = boost::signals2;
template<typename Signature>
struct my_signal
{
typedef typename bs2::signal_type<Signature,
bs2::keywords::mutex_type<my_mutex> >::type type;
};
my_signal<void ()>::type some_signal;
不幸的是,通过这样做,我也“失去”了为其他信号参数(例如组合器类型)指定替代值的能力,而不回到详细语法或定义额外的元函数,例如my_signal_with_combiner或其他东西(看起来很傻)。我不认为我可以使用默认模板参数值,因为Combiner的默认值需要拆分签名以获取返回类型。 (理想情况下,当然我喜欢适用于任何其他参数的东西,而不仅仅是组合器。)
所以,“真正的”问题是:是否有一种(简单的)方法来定义类似于signal_type的行为,其行为与其相同,但其中一个参数具有不同的默认值? (理想情况下,如果Boost.Signals2将来添加更多参数,则不需要更改。)
(另外,请不要使用C ++ 11。仍然使用较旧的编译器。)
答案 0 :(得分:0)
我已经解决了以下问题,这似乎可以解决问题。尽管如此,仍然对改进的答案感兴趣:
namespace bs2 = boost::signals2;
template <
typename Signature,
typename A1 = boost::parameter::void_,
typename A2 = boost::parameter::void_,
typename A3 = boost::parameter::void_,
typename A4 = boost::parameter::void_,
typename A5 = boost::parameter::void_,
typename A6 = boost::parameter::void_
>
struct my_signal_type : public bs2::signal_type<Signature, A1, A2, A3, A4, A5, A6>
{
typedef typename boost::parameter::value_type<args, bs2::keywords::tag::mutex_type, my_mutex>::type mutex_type;
typedef bs2::signal<
signature_type,
combiner_type,
group_type,
group_compare_type,
slot_function_type,
extended_slot_function_type,
mutex_type
> type;
};
template <
typename Signature,
typename A1 = boost::parameter::void_,
typename A2 = boost::parameter::void_,
typename A3 = boost::parameter::void_,
typename A4 = boost::parameter::void_,
typename A5 = boost::parameter::void_,
typename A6 = boost::parameter::void_
>
class MyEvent : public my_signal_type<Signature, A1, A2, A3, A4, A5, A6>::type
{
public:
typedef typename my_signal_type<Signature, A1, A2, A3, A4, A5, A6>::type base_type;
explicit MyEvent(const typename base_type::combiner_type& combiner = combiner_type())
: base_type(combiner)
{
}
};
让我有点困惑的一件事是,为什么在构造函数中使用“combiner_type”需要在类型声明中使用显式作用域 - 然后它不适用于默认参数。 (在这里删除“typename”或“base_type ::”会触发标准的“default-int”错误(这意味着“看起来不像我所知的那种类型”)。这很奇怪,因为它是在基类中定义的我猜它是一些奇怪的模板 - 部分实例化的东西。