【问题标题】:Selecting between valid and non-valid types在有效和无效类型之间进行选择
【发布时间】:2013-07-07 02:03:58
【问题描述】:

如果我们有像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;

我的问题是:有没有办法在有效类型和无效类型之间进行选择?

我目前正在实现一个事件类。事件有一个发送者参数和可变数量的事件参数:

template<typename SENDER , typename... ARGS>
class event;

所以void(SENDER&amp; , ARGS&amp;...) 类型的函数可以用作事件处理程序。 在这种情况下,处理程序被称为传递对引发事件的对象的引用(通过发送者参数)。
另一方面,我想要一种允许发送者成员函数成为事件处理程序的方法,换句话说,是void(SENDER::*)(ARGS&amp;...) 类型的函数。

问题是我不能用这样的句子:

 using handler_type = typename conditional<std::is_class<SENDER>::value,void(SENDER::*)(ARGS&...) , void(SENDER& , ARGS&...)>::type;

因为在SENDER不是类类型的情况下,第一种类型无效(使用指向非类类型成员的指针)。

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    您可以使用额外的间接级别来做到这一点:

    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;
    };
    

    用法:

    sender_type<MySender, Arg1, Arg2, Arg3>::type
    

    如果MySender 是类类型,则为void (MySender::*)(Arg1 &amp;, Arg2 &amp;, Arg3 &amp;),否则为void (*)(Sender &amp;, Arg1 &amp;, Arg2 &amp;, Arg3 &amp;)

    (您可能还希望允许联合。)

    【讨论】:

    • 感谢您的快速回复。它正是我需要的。只有一个问题:是不是variadic pack必须在模板的末尾?
    • @Manu343726 如果这正是您所需要的,也许您应该接受它作为答案?
    • 我只是在等待他对我的评论的答复。对不起
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    • 2014-08-03
    • 2017-02-23
    相关资源
    最近更新 更多