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

时间:2017-09-12 16:54:08

标签: c++ class c++11 templates

我有一个线程安全的队列类,如下所示,

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

现在,我希望此队列包含列表。所以,我使用如下:

ClassB.h:

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

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

但是,我不断收到错误,例如:

  

错误1错误C2993:&#39; std :: list&lt; _Ty&gt;&#39; :非类型的非法类型   模板参数&#39; __ formal&#39;

     

错误3错误C2975:&#39; CmdQ&#39; :无效的模板参数   &#39; unnamed-parameter&#39;,预期的编译时常量表达式

我提到了一些文档,模板类型不能接受std::list但是会​​接受指向列表的指针,因此也尝试使用指针列出如下的ClassB.h:

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

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

但我仍然面临着错误。

感谢任何帮助。

谢谢!

2 个答案:

答案 0 :(得分:2)

我认为错误的部分是

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

尝试

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

或避免它,只需写

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

反正

  

我提到了一些文档,模板类型不能接受std :: list

什么?

模板类

template <typename>
class foo { };
如果你没有参数传递它,

不接受std::list,如下所示

foo<std::list>  fl0;

(因为std::list,这是一个模板模板参数),但接受参数

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

答案 1 :(得分:2)

由于无效

,课程被打破(不编译)
 std::queue queue_;

声明。 std::queue是一个模板,您需要提供有效的模板参数。

由于你推送和弹出Q*类型的东西,唯一与模板其余部分一致的声明是

 std::queue<Q*> queue_;

现在CmdQ<std::list<Message*>*> 完全错误,因为内部队列将存储堆分配指针指向列表(存储指针本身)。你当然不想要那个。

将队列类限制为使用指针(以及拥有指向的对象)是一个糟糕的设计。严格限制选择是没有意义的。不推荐使用原始C风格指针进行常规使用,应首选智能指针。移动指针也没什么意义。拥有一个列表也没有意义,而不是它的元素。如果从类中删除所有星号,并删除对delete的调用,则模板将变得更简单,更通用,更一致。然后你可以使用

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

或您喜欢的任何组合。你可能不得不在这里和那里添加几个电话std::move。您可能还想添加一个可选的元素删除器,以防万一有人因为某些莫名其妙的原因而需要使用带有原始指针的模板。