简体   繁体   English

C ++类模板类型std :: list

[英]C++ Class template type std::list

I have a thread safe queue class like below, 我有一个如下的线程安全队列类,

Class CmdQ: CmdQ类:

template <typename Q>
class CmdQ
{
public:
    CmdQ() :
        queue_(),
        queueMutex_(){};
    ~CmdQ() {
        while (!queue_.empty()) {
            Q* element(std::move(this->queue_.front()));
            this->queue_.pop();
            delete element;
        }
    };
    void push(Q* commands) {
        std::unique_lock<std::mutex> lock(this->queueMutex_);

        queue_.push(commands);
        this->mutexCondition_.notify_all();
    }
    void pop() {
        std::unique_lock<std::mutex> lock(this->queueMutex_);
        while(this->queue_.empty())this->mutexCondition_.wait(lock);
        Q* element(std::move(this->queue_.front()));
        this->queue_.pop();
        delete element;
    }

    Q* front() {
        std::unique_lock<std::mutex> lock(this->queueMutex_);
        while(this->queue_.empty())this->mutexCondition_.wait(lock);        if (!queue_.empty()) {
            return (queue_.front());
        }
        return NULL;
    }

    bool empty() {
        std::unique_lock<std::mutex> lock(this->queueMutex_);
        return queue_.empty();
    }

    void clear() {
        std::unique_lock<std::mutex> lock(this->queueMutex_);

        while (!queue_.empty()) {
            Q* element(std::move(this->queue_.front()));
            this->queue_.pop();
            delete element;
        }
    }

    unsigned int size() {
        std::unique_lock<std::mutex> lock(this->queueMutex_);
        return queue_.size();
    }

private:
    std::queue queue_;
    std::mutex queueMutex_;
    std::condition_variable mutexCondition_;
};

Now, I want this queue to contain lists. 现在,我希望此队列包含列表。 And so, I used as below: 因此,我按如下方式使用:

ClassB.h: ClassB.h:

template<typename std::list<Message*>>
class CmdQ;

CmdQ<std::list<Message*>>* msgListQ_;

But, I keep getting the errors such as: 但是,我不断收到如下错误:

Error 1 error C2993: 'std::list<_Ty>' : illegal type for non-type template parameter '__formal' 错误1错误C2993:'std :: list <_Ty>':非类型模板参数'__formal'的非法类型

Error 3 error C2975: 'CmdQ' : invalid template argument for 'unnamed-parameter', expected compile-time constant expression 错误3错误C2975:“ CmdQ”:“未命名参数”的模板参数无效,预期的编译时常量表达式

I referred to some documentation that template type cannot accept std::list but will accept pointer to lists and so also tried using pointer to list like below in ClassB.h: 我提到了一些文档,模板类型不能接受std::list但是可以接受指向列表的指针,因此也尝试在ClassB.h中使用指向列表的指针:

template<typename std::list<Message*>*>
class CmdQ;

CmdQ<std::list<Message*>*>* msgListQ_; 

But I still keep facing errors. 但是我仍然面对错误。

Any help is appreciated. 任何帮助表示赞赏。

Thanks! 谢谢!

I suppose the wrong part is the typename in 我想错误的部分是typename

template<typename std::list<Message*>*>
class CmdQ;

try with 尝试

template <std::list<Message*>*>
class CmdQ;

or avoid it and simply write 或避免它,只需写

CmdQ<std::list<Message*>*>* msgListQ_; 

Anyway 无论如何

I referred to some documentation that template type cannot accept std::list 我提到了一些文档,模板类型不能接受std :: list

What? 什么?

a template class 模板类

template <typename>
class foo { };

doesn't accept std::list if you pass it without argument, as follows 如果不带参数传递它,则不接受std::list ,如下所示

foo<std::list>  fl0;

(because std::list , in this way, is a template-template argument) but accept it with arguments (因为std::list这样,它是一个template-template参数),但是要接受带参数的参数

foo<std::list<int>> fl1;

The class is broken (doesn't compile) because of the invalid 由于无效,该类已损坏(无法编译)

 std::queue queue_;

declaration. 宣言。 std::queue is a template and you need to supply a valid template argument. std::queue是模板,您需要提供有效的模板参数。

Since you push and pop things of type Q* , the only declaration consistent with the rest of the template would be 由于您推送和弹出Q*类型的东西,因此唯一与模板其余部分一致的声明是

 std::queue<Q*> queue_;

Now CmdQ<std::list<Message*>*> is totally wrong as the internal queue would store heap-allocated pointers to pointers of lists (that store pointers themselves). 现在, CmdQ<std::list<Message*>*> 完全错误,因为内部队列将存储指向列表指针的堆分配指针 (自身存储指针)。 You certainly don't want that. 您当然不想要那样。

It's a bad design to constrain your queue class to work with pointers (and to own the pointed object) though. 但是,限制队列类使用指针(并拥有指向的对象)是一个糟糕的设计。 It makes little sense to limit the choice so severely. 如此严格地限制选择毫无意义。 Raw C-style pointers are not recommended for general use, smart pointers should be preferred. 不建议一般使用Raw C风格的指针,最好使用智能指针。 It also makes little sense to move pointers. 移动指针也没有多大意义。 It also makes little sense to own a list, bit not its elements. 拥有一个列表也没有多大意义,而不是拥有其元素。 If you remove all asterisks from the class, and also remove the call to delete , the template becomes simpler, more generic, and more consistent. 如果您从该类中删除所有星号,并且还删除了对delete的调用,则该模板将变得更简单,更通用且更一致。 You can then use 然后,您可以使用

CmdQ<std::list<Message>>   // store lists by value
CmdQ<std::list<Message*>*> // store pointers to lists of pointers (not recommended)
CmdQ<std::unique_ptr<std::list<std::shared_ptr<Message>>>> // etc

or any combination you like. 或您喜欢的任何组合。 You will probably have to add a couple of calls to std::move here and there. 您可能必须添加几个对std::move的调用。 You may also want to add an optional element deleter, just in case someone would want for some inexplicable reason to use your template with raw pointers. 您可能还想添加一个可选的元素删除器,以防万一有人出于某些无法解释的原因而希望将模板与原始指针一起使用。

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

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