树莓派编译报错:std::lock_guard缺失模板参数问题排查
问题:跨平台编译C++线程安全队列类时出现模板参数缺失错误
你编写了如下简易线程安全队列类,作为大型项目的一部分:
#pragma once #include <mutex> #include <queue> template <typename T> class MessagesQueuee { std::mutex mutex; std::queue<T> queue; public: MessagesQueuee() {}; ~MessagesQueuee() {}; void push(T&& item) { std::lock_guard lock(mutex); queue.push(item); } T& front() { std::unique_lock lock(mutex); return queue.front(); } void pop() { std::lock_guard lock(mutex); queue.pop(); } };
该代码在Ubuntu(amd64)平台使用g++可正常编译,但在树莓派平台编译时,出现错误提示:
missing template arguments before lock
错误指向std::lock_guard lock(mutex);等相关行。请问代码是否存在问题?若有,该如何解决?
问题原因
这是C++标准版本差异导致的问题:
- C++17及以后的标准支持类模板参数推导(CTAD),可以直接写
std::lock_guard lock(mutex);,编译器会从构造函数参数mutex(类型为std::mutex)推导出std::lock_guard的模板参数为std::mutex。 - 树莓派平台的g默认可能使用了C17之前的标准(比如C11或C14),这些标准不支持CTAD,因此必须显式指定模板参数,否则编译器会报错"缺失模板参数"。
解决方法
方法1:显式指定模板参数(兼容所有C++11及以后版本)
将std::lock_guard和std::unique_lock的声明改为显式指定模板参数std::mutex,修改后的代码如下:
#pragma once #include <mutex> #include <queue> template <typename T> class MessagesQueuee { std::mutex mutex; std::queue<T> queue; public: MessagesQueuee() {}; ~MessagesQueuee() {}; void push(T&& item) { std::lock_guard<std::mutex> lock(mutex); queue.push(std::move(item)); // 优化:用std::move传递右值,避免不必要的拷贝 } T& front() { std::unique_lock<std::mutex> lock(mutex); return queue.front(); } void pop() { std::lock_guard<std::mutex> lock(mutex); queue.pop(); } };
方法2:编译时指定C++17或更高标准
如果树莓派的g版本支持C17(g++ 7及以上版本支持),可以在编译时添加参数-std=c++17,例如:
g++ -std=c++17 your_source_file.cpp -o your_program
这种方式不需要修改代码,但依赖编译器的版本支持。
内容的提问来源于stack exchange,提问作者pi.314
相关产品推荐
相关产品推荐

