c++ - 需要语法帮助以根据模板参数的类型专门化类方法

标签 c++ c++11 stl template-meta-programming typetraits

我有一个使用 std::priority_queue<std::shared_ptr<T>> 的通用线程安全队列类作为容器类型(通过模板参数指定)。但是,我想另外专门化它以使用更简单的 std::queue<std::shared_ptr<T>> .不幸的是,这将意味着使用不同的技术来检索队列的最顶层元素( top() 用于 std::priority_queue<T>front() 用于 std::queue<T> )。我有一个 live coliru demo 显示了 priority_queue 的工作原型(prototype)类型。但是,如果我尝试使用 std::queue通过添加以下代码:

我从编译器中得到了预期的错误,表明 std::queue没有top()方法。

我怀疑获得此权利的关键是使用 std::enable_if_t<T>对于每个 wait_and_pop方法。我该怎么做?

编辑:感谢 T.C 的建议,我相信适用于 GCC 和 MSVC 的通用解决方案需要对 UtlThreadSafeQueue 进行以下调整。有更新直播coliru demo here :

// Note that overloading 2 function using expression SFINAE
// as shown here does not work on MSVC compiler - it does
// work on later builds of GCC though.
//template<class Q>
//auto front_or_top(Q& q) -> decltype(q.front()) {
//    return q.front();
//}
//template<class Q>
//auto front_or_top(Q& q) -> decltype(q.top()) {
//    return q.top();
//}

// this is a specific overload to work around the missing
// expression SFINAE in MSVC - for the std::queue<T>
template<class T>
auto front_or_top(std::queue<T>& q) -> decltype(q.front()) {
    return q.front();
}

// this is a specific overload to work around the missing
// expression SFINAE in MSVC - for the std::priority_queue<T>
template<class T>
auto front_or_top(std::priority_queue<T>& q) -> decltype(q.top()) {
    return q.top();
}

/**
 * default type of container is a std::queue - which by default
 * uses a std::deque<> of std::shared_ptr<T>'s. The default
 * std::queue<T> does not need to order elements, and as
 * such, it does not require an element comparator as is
 * required by its priority queue counterpart.
 *
 * For the UtlThreadSafeQueue variant that uses a priority
 * queue, we must define a comparator to compare
 * <code>std::shared_ptr<T>'s</code>.
 *
 * To use a UtlThreadSafeQueue with a priority_queue container,
 * use as follows:
 *
 * <pre>{@code
 * // using priority queue
 * UtlThreadSafeQueue<PriorityLevel, std::priority_queue<
 *     std::shared_ptr<PriorityLevel>,
 *     std::vector<std::shared_ptr<PriorityLevel>>,
 *     ptr_less<std::shared_ptr<PriorityLevel>>>> prtyQ;
 *
 * }</pre>
 */
template<typename T, typename Cont = std::queue<std::shared_ptr<T>>>
class UtlThreadSafeQueue {
private:
    mutable std::mutex mut;
    Cont data_queue;
    std::condition_variable data_cond;
    std::size_t capacity;
    std::atomic<bool> shutdownFlag;
public:

最佳答案

使用重载的自由函数助手。一种可能的方式:

template<class Q>
auto front_or_top(Q& q) -> decltype(q.front()) { return q.front(); }

template<class Q>
auto front_or_top(Q& q) -> decltype(q.top()) { return q.top(); }

然后执行front_or_top(cont)。请注意,如果容器同时定义了 front()top(),这是不明确的。

或者,您也可以只为 queuepriority_queue 重载 front_or_top:

template<class T, class Cont>
auto front_or_top(std::queue<T, Cont>& q) -> decltype(q.front()) { return q.front(); }

template<class T, class Cont, class Comp>
auto front_or_top(std::priority_queue<T, Cont, Comp>& q) -> decltype(q.top()) { return q.top(); }

关于c++ - 需要语法帮助以根据模板参数的类型专门化类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31928111/

相关文章:

c++ - std::move 和 unique_ptr::reset 之间有什么区别?

c++ - 作为结构内部字段的映射的初始化值?

c# - 从控制句柄获取进程

c++ - OpenCV 错误 : "LINK : fatal error LNK1104: cannot open file ' opencv_core231d. 库'”

c++ - noexcept 有什么用?

c++ - 在用户定义的类中清空 std::vector 时未释放内存

c++ - 如何避免调用 vector 中元素的复制构造函数

c++ - 如何将值插入已排序的 vector 中?

c++ - 如何将 std::vector<char*> 转换为 char**?

c++ - C++ friend 模板函数:找不到函数定义