从传递给构造函数的参数类型中推导出可变参数成员类型

时间:2017-08-29 11:58:04

标签: c++ c++14 variadic-templates

我试图从传递给它的类'构造函数的参数类型中推断出成员变量的类型。类的构造函数(PublishSubscribe类)接收两个参数,每个参数代表可变参数类型(一个可变参数包用于发送,一个用于接收)。

我正在努力实现的代码如下:

#include <tuple>

template <typename... Types>
struct TopicTypes {};

TopicTypes<int> type_subscribe_topics;
TopicTypes<int,double> type_publish_topics;

template <typename... TReceives>
class PublishSubscribe
{
  public:
    template <  typename... TReceives,  template <typename...> class TR,
                typename... TSends,     template <typename...> class TS>
    PublishSubscribe(const TR<TReceives...>&,
                     const TS<TSends...>&){}

    private:
    std::tuple<TReceives...> member_; 
};

class UserClass : public PublishSubscribe{
    public:
     UserClass()
        : PublishSubscribe(
                type_subscribe_topics,
                type_publish_topics
        ){}
};

int main()
{
    return 0;
}

我收到以下编译错误:

variadic3.cpp:13:17: error: declaration of 'class ... TReceives'
     template <  typename... TReceives,  template <typename...> class TR,
                 ^
variadic3.cpp:9:11: error:  shadows template parm 'class ... TReceives'
 template <typename ... TReceives>

如何使用type_subscribe_topics类型模板化PublishSubscribe类?在这种特殊情况下,我需要PublishSubscribe<magic(decltype(type_subscribe_topics))>默认为PublishSubscribe<int>

非常感谢提前!

1 个答案:

答案 0 :(得分:2)

您不能在类模板和成员函数模板中使用相同的模板名称。

template <typename... TReceives>
class PublishSubscribe

template <  typename... TReceives,  template <typename...> class TR,
            typename... TSends,     template <typename...> class TS>
PublishSubscribe(const TR<TReceives...>&,
                 const TS<TSends...>&){}    

两者都使用TReceives。您需要更改其中一个模板中的名称,或者,如果您使用传递给该类的TReceives,则可以从函数中删除它,看起来像

template <                          template <typename...> class TR,
            typename... TSends,     template <typename...> class TS>
PublishSubscribe(const TR<TReceives...>&,
                 const TS<TSends...>&){}

您无法使用构造函数的模板参数来定义member_元组应使用的类型。你可以让这个类不那么通用,只需要像

这样的元组
template <typename T> 
class PublishSubscribe 

然后你会像

一样使用它
PublishSubscribe<decltype(some_tuple)> foo(some_tuple, some_other_tuple); 

member_将成为T member_;