如果我们有类似的模板元函数std::conditional,我们可以根据布尔编译时条件"选择"类型.例如:
template < bool CONDITION, typename T, typename U >
struct conditional;
template < typename T, typename U >
struct conditional < true, T, U >
{
using type = T;
};
template < typename T, typename U >
struct conditional < false, T, U >
{
using type = U;
};
const bool whats_big = sizeof( int ) > sizeof( double );
using bigger_type = typename conditional<whats_big , int , double>::type;
Run Code Online (Sandbox Code Playgroud)
我的问题是:有没有办法在有效类型和无效类型之间进行选择?
我目前正在实施一个活动类.事件具有sender参数和可变数量的事件args:
template<typename SENDER , typename... ARGS>
class event;
Run Code Online (Sandbox Code Playgroud)
因此具有类型的函数void(SENDER& , ARGS&...)可以用作事件处理程序.在这种情况下,处理程序被称为传递对引发事件的对象的引用(发送者参数).
另一方面,我想要一种方法来允许发送方成员函数成为事件的处理程序,换句话说,类型的函数void(SENDER::*)(ARGS&...).
问题是我不能使用如下句子:
using handler_type = typename conditional<std::is_class<SENDER>::value,void(SENDER::*)(ARGS&...) , void(SENDER& , ARGS&...)>::type;
Run Code Online (Sandbox Code Playgroud)
因为在SENDER不是类类型的情况下,第一种类型是无效的(使用指向非类型成员的指针).
您可以使用额外的间接级别来执行此操作:
template <bool, typename T, typename ...Args>
struct sender_chooser
{
using type = void(*)(T &, Args &...);
};
template <typename T, typename ...Args>
struct sender_chooser<true, T, Args...>
{
using type = void (T::*)(Args &...);
};
template <typename T, typename ...Args>
struct sender_type
{
using type =
typename sender_chooser<std::is_class<T>::value, T, Args...>::type;
};
Run Code Online (Sandbox Code Playgroud)
用法:
sender_type<MySender, Arg1, Arg2, Arg3>::type
Run Code Online (Sandbox Code Playgroud)
这是void (MySender::*)(Arg1 &, Arg2 &, Arg3 &)if MySender类型或其他类型void (*)(Sender &, Arg1 &, Arg2 &, Arg3 &).
(你可能也想允许工会.)