Задание альтернативных значений по умолчанию для сигналов повышения2
Библиотека сигналов2 Boost определяет хороший способ прохождения альтернативных параметров для некоторых из его расширенных функций (через библиотеку параметров). Когда один из этих альтернативных параметров довольно часто встречается в моем коде, я хочу сделать помощника, чтобы еще больше упростить его использование; Например, чтобы указать альтернативный тип мьютекса, я могу сделать это:
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 по умолчанию требуется разделить Signature, чтобы получить тип возвращаемого значения. (И в идеале, конечно, я хотел бы что-то, что работает для любых других параметров, а не только для объединителя.)
Итак, "реальный" вопрос: есть ли (простой) способ определить что-то вроде signal_type, которое ведет себя идентично ему, но имеет другое значение по умолчанию для одного из параметров? (В идеале, это не должно требовать изменения, если Boost.Signals2 добавляет больше параметров в будущем.)
(Также, пожалуйста, не используйте C++11. Все еще используете более старый компилятор.)
1 ответ
Я разработал следующее, которое, кажется, делает свое дело. Все еще заинтересованы в улучшенных ответах, хотя:
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" (что означает "это не похоже на тип, который я знаю"). Это странно, так как оно определено в базовом классе Я предполагаю, что это какая-то странная вещь частичного создания шаблона.