使用tuple为何触发C++编译警告?
搞定C++17编译时的
use of function template name with no prior declaration警告 嘿,咱们先把这个警告的来龙去脉说清楚:你代码里的get<0>(t)和get<1>(t)没加std::前缀,这就是问题的根源!
get这个函数模板是定义在<tuple>头文件的std命名空间下的,在C17标准里,当你用显式模板参数(就是<0>这种尖括号里的数字)调用函数模板时,编译器要求必须能在当前作用域找到这个模板的声明。你直接写get的话,编译器根本不知道你指的是std::get,自然就抛出警告了。而C20(也就是警告里提的C2a)才放宽了这个规则,允许编译器通过参数依赖查找自动找到std里的get,但你用的是C17编译选项,肯定不兼容这个新特性嘛。
修正后的代码
#include <iostream> #include <vector> #include <string> #include <tuple> int main() { std::vector<std::tuple<std::string, int> > vec; vec.insert(vec.begin(), std::tuple("John", 1)); // C++17支持自动推导tuple的模板参数,这行没问题 for (auto t : vec) { // 核心修正:给get加上std::命名空间前缀 std::cout << std::get<0>(t) + " has id of " << std::get<1>(t) << std::endl; } return 0; }
额外小提示
- 关于
std::tuple("John", 1):这是C++17的类模板实参推导功能,编译器会自动识别出这个tuple的类型是std::tuple<std::string, int>。如果你的编译器版本比较老(比如有些早期的GCC版本),可以换成std::make_tuple("John", 1),或者直接写std::tuple<std::string, int>("John", 1),效果完全一样。 - 你的编译命令
g++ -o vector_practice vector_practice.cpp -std=c++17不用改,代码修正后警告就会消失啦。
内容的提问来源于stack exchange,提问作者Dan Tang
相关产品推荐
相关产品推荐

