You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设计模板让ThreadSafeQueue的get()适配std::queue.front()与std::priority_queue.top()

实现ThreadSafeQueue的get()方法适配不同队列类型

你的模板已限定QueueType只能是std::queue<T>或std::priority_queue<T>,要实现get()方法分别调用两者的front()和top(),可以用以下几种实用方案:

方法1:C++20 constexpr if 直接判断

如果项目支持C++20,这是最简洁的实现方式,利用编译期分支直接匹配对应队列的方法:

#include <queue>
#include <type_traits>

template<typename T, 
typename QueueType,
typename = std::enable_if_t<std::is_same_v<QueueType, std::queue<T>> || std::is_same_v<QueueType, std::priority_queue<T>>>>
class ThreadSafeQueue {
private:
    QueueType q;

public:
    T& get() {
        if constexpr (std::is_same_v<QueueType, std::queue<T>>) {
            return q.front();
        } else {
            // 模板已限定类型,此处必然是std::priority_queue<T>
            return q.top();
        }
    }
};

方法2:标签分发(Tag Dispatch)

这是C++11及以上版本通用的经典适配方式,通过辅助标签区分不同队列类型:

#include <queue>
#include <type_traits>

template<typename T, 
typename QueueType,
typename = std::enable_if_t<std::is_same_v<QueueType, std::queue<T>> || std::is_same_v<QueueType, std::priority_queue<T>>>>
class ThreadSafeQueue {
private:
    QueueType q;

    // 定义区分队列类型的标签结构体
    struct QueueTag {};
    struct PriorityQueueTag {};

    // 针对std::queue的实现
    T& get_impl(QueueTag) {
        return q.front();
    }

    // 针对std::priority_queue的实现
    T& get_impl(PriorityQueueTag) {
        return q.top();
    }

public:
    T& get() {
        if constexpr (std::is_same_v<QueueType, std::queue<T>>) {
            return get_impl(QueueTag{});
        } else {
            return get_impl(PriorityQueueTag{});
        }
    }
};

方法3:SFINAE 重载匹配

利用SFINAE特性,为不同队列类型分别重载get()方法,适配C++11及以上版本:

#include <queue>
#include <type_traits>

template<typename T, 
typename QueueType,
typename = std::enable_if_t<std::is_same_v<QueueType, std::queue<T>> || std::is_same_v<QueueType, std::priority_queue<T>>>>
class ThreadSafeQueue {
private:
    QueueType q;

public:
    // 仅当QueueType为std::queue<T>时启用该版本
    template<typename Q = QueueType>
    std::enable_if_t<std::is_same_v<Q, std::queue<T>>, T&> get() {
        return q.front();
    }

    // 仅当QueueType为std::priority_queue<T>时启用该版本
    template<typename Q = QueueType>
    std::enable_if_t<std::is_same_v<Q, std::priority_queue<T>>, T&> get() {
        return q.top();
    }
};

额外提示

当前模板缺少线程安全的核心同步机制,实际使用时需添加互斥锁避免多线程竞态,示例如下:

#include <queue>
#include <type_traits>
#include <mutex>

template<typename T, 
typename QueueType,
typename = std::enable_if_t<std::is_same_v<QueueType, std::queue<T>> || std::is_same_v<QueueType, std::priority_queue<T>>>>
class ThreadSafeQueue {
private:
    QueueType q;
    std::mutex mtx; // 互斥锁

public:
    T& get() {
        std::lock_guard<std::mutex> lock(mtx); // 自动加锁解锁
        if constexpr (std::is_same_v<QueueType, std::queue<T>>) {
            return q.front();
        } else {
            return q.top();
        }
    }

    // 配套的线程安全push示例
    void push(const T& val) {
        std::lock_guard<std::mutex> lock(mtx);
        q.push(val);
    }
};

内容的提问来源于stack exchange,提问作者f1msch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 00:20:10