C++ Traits类作为模板参数
我的代码中散布了traits类,它们遵循相同的基本习惯用法:C++ Traits类作为模板参数,c++,templates,c++14,template-meta-programming,traits,C++,Templates,C++14,Template Meta Programming,Traits,我的代码中散布了traits类,它们遵循相同的基本习惯用法: 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_
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;
};
但这不起作用,因为
我知道如果我总是在模板实例化中使用traits类(并修改traitchecker以接受它),我可以解决这个问题,即
具有\u基本\u帧\u类型::值
但我不想这样做,因为这将是忘记和通过在一个非特质类。事实上,这就是我最初编写代码的方式,直到我多次忘记trait-one并对其进行重构
有什么方法可以修改我的trait类习惯用法来解决模板参数问题吗?框架:
#include <type_traits>
template <typename...>
using void_t = void;
template <typename AlwaysVoid, template <typename...> class Operation, typename... Args>
struct detect_impl : std::false_type {};
template <template <typename...> class Operation, typename... Args>
struct detect_impl<void_t<Operation<Args...>>, Operation, Args...> : std::true_type {};
template <template <typename...> class Operation, typename... Args>
using detect = detect_impl<void, Operation, Args...>;
#包括
模板
使用void\u t=void;
模板
struct detect_impl:std::false_type{};
模板
struct detect_impl类似于?@Piotr我不擅长读取模板元代码,但我不确定您的traits别名是否具有与我的traits类相同的属性,即,无论模板输入如何,都将始终定义typedef,但如果不是由t
定义typedef,则typedef将无效。此外,我不清楚它是否可以扩展到定义多个typedef的traits类?你说的“它不可伸缩”是什么意思?如果只是一个特征,为什么需要一个虚拟的void
typedef呢?我希望像has\u base\u frame\u type::value
这样的东西可以编译(并且让valuefalse
),它可以编译并计算为false
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 {};
has_base_frame_type<frame_traits<MyClass>>::value
#include <type_traits>
template <typename...>
using void_t = void;
template <typename AlwaysVoid, template <typename...> class Operation, typename... Args>
struct detect_impl : std::false_type {};
template <template <typename...> class Operation, typename... Args>
struct detect_impl<void_t<Operation<Args...>>, Operation, Args...> : std::true_type {};
template <template <typename...> class Operation, typename... Args>
using detect = detect_impl<void, Operation, Args...>;
template <class Frame>
using frame_traits = typename Frame::base_frame_type;
template <class Frame>
using other_frame_traits = typename Frame::other_frame_type;
template <typename T, template <typename...> class Traits = frame_traits>
using has_frame_type = detect<Traits, T>;
struct A
{
using base_frame_type = void;
};
struct B
{
using other_frame_type = void;
};
int main()
{
static_assert(has_frame_type<A>{}, "!"); // default
static_assert(!has_frame_type<B>{}, "!"); // default
static_assert(!has_frame_type<A, other_frame_traits>{}, "!"); // non-default
static_assert(has_frame_type<B, other_frame_traits>{}, "!"); // non-default
}