当类作为另一模板的模板参数时,能否使用类模板实参推导?
类模板实参推导在
std::vector<std::pair>中的使用问题 你这段代码里遇到的编译错误,本质是C++的类模板实参推导(CTAD)不支持嵌套推导导致的。当你单独写std::vector v{1,2,3}或者std::pair p{1,"a"s}时,编译器可以直接从初始化元素推导出模板参数;但当你尝试写std::vector<std::pair> vp{...}时,编译器没办法从初始化列表里的元素反向推导std::pair的模板参数——因为这需要先推导内层std::pair的类型,再用这个类型推导外层std::vector的元素类型,而CTAD不支持这种“嵌套式”的推导逻辑。
那有没有办法让推导生效?当然有,下面给你几种可行的方案:
方案1:显式指定std::pair的模板参数
这是最直接的解决方式,明确告诉编译器std::pair的模板类型:
#include <string> #include <vector> #include <utility> using namespace std::string_literals; int main(){ std::vector v{1,2,3}; std::pair p{1,"a"s}; // 显式指定pair的模板参数,vector就能正常推导元素类型 std::vector<std::pair<int, std::string>> vp{{1,"a"s}, {2, "b"s},{3,"c"s}}; }
方案2:让每个std::pair先完成推导,再让vector推导
通过显式构造每个std::pair,先让它们各自完成模板参数推导,再把这些已推导类型的对象交给std::vector,这样外层的vector就能自动推导元素类型了:
#include <string> #include <vector> #include <utility> using namespace std::string_literals; int main(){ std::vector v{1,2,3}; std::pair p{1,"a"s}; // 每个pair先单独推导,vector再推导元素类型 auto vp = std::vector{std::pair{1,"a"s}, std::pair{2, "b"s}, std::pair{3,"c"s}}; }
方案3:使用std::make_pair(C++11及以后可用)
虽然C++17之后更推荐直接用类模板推导,但std::make_pair也能帮你完成类型推导,间接解决问题:
#include <string> #include <vector> #include <utility> using namespace std::string_literals; int main(){ std::vector v{1,2,3}; std::pair p{1,"a"s}; // make_pair会自动推导参数类型,vector再基于此推导 auto vp = std::vector{std::make_pair(1,"a"s), std::make_pair(2,"b"s), std::make_pair(3,"c"s)}; }
总结一下:你没办法让std::vector<std::pair>直接通过初始化列表完成嵌套推导,必须要么显式指定std::pair的模板参数,要么先让每个std::pair完成自身的类型推导,再交给std::vector处理。
内容的提问来源于stack exchange,提问作者NoSenseEtAl
相关产品推荐
相关产品推荐

