【问题标题】:Deducing variadic member type from types of arguments passed to constructor从传递给构造函数的参数类型推断可变成员类型
【发布时间】:2017-08-29 11:58:03
【问题描述】:

我试图从传递给其类的构造函数的参数类型中推断出成员变量的类型。类的构造函数(一个 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&lt;magic(decltype(type_subscribe_topics))&gt;,在这种特殊情况下默认为PublishSubscribe&lt;int&gt;..

非常感谢!

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 对!我使用相同的类型是因为我希望 member_ 变量具有与传递给构造函数的参数类型相同的类型。
    • @MihaiGalos 哦,我不确定你能做到这一点。 AFAIK 成员变量不能依赖于成员函数模板参数,因为编译类时不知道。
    • 嗯。我知道了。在这里可以做些什么来创建一个“通用”模板来模板 type_subscribe_topics PublishSubscribe?
    • @MihaiGalos 您愿意接受一个元组作为模板类型,而不是完全通用?如果是这样,您可以只使用template &lt;typename... TReceives&gt; class PublishSubscribe,然后您会像PublishSubscribe&lt;decltype(some_tuple)&gt; foo(some_tuple, some_other_tuple);member_ 一样使用它,这将变成T member_;
    • 很遗憾没有。我需要用这个模板开发这个 PublishSubscribe 类。如果不可能,我需要从它继承时专门化该类:class UserClass : public PublishSubscribe&lt;int&gt;.
    猜你喜欢
    • 2020-10-17
    • 1970-01-01
    • 2019-09-23
    • 2022-01-26
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    相关资源
    最近更新 更多