я классы свойств посыпают о моем коде, которые следуют один и тот же основной идиомы:Черты характера класса в качестве параметра шаблона шаблон
template<class Frame, typename = void>
struct frame_traits
{
typedef void base_frame_type;
};
template<class Frame>
struct frame_traits<Frame, typename std::void_t<
typename Frame::base_frame_type>::type>
{
typedef typename Frame::base_frame_type base_frame_type;
};
и у меня есть куча признака шашек, которые используют их, которые также следуют аналогичной идиомы :
template <typename T>
struct has_base_frame_type : std::integral_constant<bool,
!std::is_same<typename frame_traits<T>::base_frame_type, void>::value>::type {};
однако, оказывается, что has_base_frame_type
стало полезным для нескольких концепций в моем коде, и я хотел бы обобщить его дальше, так что я могу передать класс черты в качестве дополнительного параметра:
template <typename T, template<typename> class Traits = frame_traits>
struct has_base_frame_type : std::integral_constant<bool,
!std::is_same<typename Traits<T>::base_frame_type, void>::value>::type {};
Это не работает, поскольку, начиная с templates with default arguments cannot be used as template template parameters.
Я знаю, что я мог бы обойти эту проблему, если я всегда использую класс черты в шаблоне конкретизации (и изменить признак проверку, чтобы принять его), а именно
has_base_frame_type<frame_traits<MyClass>>::value
, но я не хочу делать это, потому что было бы all too easy забыть и пройти в классе без признаков. Фактически, именно так я изначально написал код, пока я не забыл эту черту слишком много раз и реорганизовал ее.
Есть ли какой-нибудь способ изменить свой класс idiom, чтобы обойти проблему с шаблоном шаблона шаблона?
Что-то вроде [идиомы обнаружения] (http://coliru.stacked-crooked.com/a/779edd372df54f26)? –
@Piotr Я не очень хорошо читаю метакод шаблона, но я не уверен, что ваши псевдонимы черт имеют те же свойства, что и мой класс признаков, а typedef всегда будет определен независимо от того, какой ввод шаблона, но будет недействительным если typedef не был определен 'T'. Кроме того, для меня не очевидно, что он масштабирует классы признаков, которые определяют несколько типов typedef. –
Вы имеете в виду [это] (http://coliru.stacked-crooked.com/a/0108aa409e8e95fe)? Что вы подразумеваете под словом «оно не масштабируется»? Зачем вам нужен фиктивный 'void' typedef, если это просто черта? –