简体   繁体   English

具有类名的可变参数模板

[英]Variadic template with class names

I've this template 我有这个模板

template <typename T> 
class Publisher
{
public:
    Publisher(){}
    ~Publisher(){}
}

and I've this variadic template 我有这个可变的模板

template <typename First, typename... Rest>
class PublisherContainer
{
    PublisherContainer();
    ~PublisherContainer();
}

In the PublisherContainer constructor I want to create a Publisher for every template argument: PublisherContainer构造函数中,我想为每个模板参数创建一个Publisher

template <typename First, typename... Rest>
PublisherContainer<First, Rest...>::PublisherContainer()
{
    Publisher<First> publisher;
    // create other publisher here.
}

So I can do 所以我可以做

PublisherContainer<ClassA, ClassB, ClassC> myPublisher;

How can I invoke Publisher for every template argument? 如何为每个模板参数调用Publisher

Class templates cannot have "pack members". 类模板不能具有“包成员”。 Parameter packs must either be forwarded or unpacked; 参数包必须转发或解包; they cannot be used like types. 它们不能像类型一样使用。

The easiest answer is to not reinvent the wheel and use the purpuse-built product type, std::tuple : 最简单的答案是不要重新发明轮子,而是使用由紫色构建的产品类型std::tuple

template <typename ...Args>
struct PublisherContainer
{
    std::tuple<Publisher<Args>...> publisher;
};

(Note that "container" is probably a bad name, since in the idiom of standard C++, containers are things that model iterable ranges of elements. A tuple is a product ("one of each"), not a range. Maybe "PublisherHolder" is more appropriate, or drop the wrapper layer entirely and just use tuples directly.) (请注意,“容器”可能是一个不好的名字,因为在标准C ++的惯用语中,容器是对元素的可迭代范围进行建模的对象。元组是一个产品(“每个”中的一个),而不是范围。也许是“ PublisherHolder” “是更合适的选择,或者完全删除包装层,而直接使用元组即可。)

Kerrek SB is semi-correct in his answer. Kerrek SB的回答是半正确的。 It is correct that you cannot have packed members in the way you are currently trying to do this, but you can do it with inheritance. 正确的是,您不能以当前尝试的方式打包成员,但是可以通过继承来实现。

First we will define a base class: 首先,我们将定义一个基类:

template<typename T>
class PublisherBase{
    public:
        int some_member;
        void some_method(){}
};

then we need a class to contain our base: 那么我们需要一个类来包含我们的基础:

template<typename T>
class Publisher{
    public:
        PublisherBase<T> self;
};

then we create our holder or 'container' 然后我们创建我们的容器或“容器”

template<typename First, typename ... Rest>
class PublisherContainer: public Publisher<First>, Publisher<Rest>...{};

which we can use like so: 我们可以这样使用:

int main(int argc, char *argv[]){
    PublisherContainer<int, float, double, short> container;
    container.Publisher<float>::self.some_method();
    container.Publisher<short>::self.some_member = 5;
}

The syntax is kinda weird, but it achieves what you asked. 语法有点怪异,但是可以满足您的要求。 The only issue with this approach is that you are restricted to only one publisher per type; 这种方法的唯一问题是,每种类型只能限制一个发布者。 but that also may be desired. 但这可能也是理想的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM