C++17中如何为std::array<std::string,N>参数实现编译期大小推导?
解决std::array作为函数参数时无法推导模板大小的问题
直接定义std::array时能自动推导类型和大小,靠的是C++17引入的类模板参数推导(CTAD)——编译器会根据初始化列表里的元素,自动补全std::array的模板参数。但把std::array<std::string, N>&作为函数模板参数时,这事就行不通了:函数模板推导和类模板推导是两条独立的流程,初始化列表本身并不是std::array对象,编译器没法触发CTAD来算出N的值,自然就报错了。
下面给你几个实用的解决办法:
方案1:显式指定模板参数(简单但不灵活)
调用函数时直接写明N的大小,编译器就能匹配到对应的模板实例:
#include <array> #include <string> using namespace std::string_literals; template<size_t N> void Test(std::array<std::string, N> &argument) { } int main(void) { Test<2>({ "Hello"s, "World"s }); // 手动指定N=2,编译通过 }
缺点是元素数量变了就得手动改数字,不够灵活。
方案2:改用数组引用作为函数参数(自动推导大小)
调整函数模板,让它先接受一个数组引用——编译器能直接从初始化列表推导元素类型和数组大小,你再在函数内部把数组转成std::array用:
#include <array> #include <string> using namespace std::string_literals; template<typename T, size_t N> void Test(const T (&arr)[N]) { std::array<T, N> argument; // 把数组元素拷贝到std::array(如果是编译期场景,只要T支持constexpr拷贝就能完成) for (size_t i = 0; i < N; ++i) { argument[i] = arr[i]; } // 这里写你的业务逻辑 } int main(void) { Test({ "Hello"s, "World"s }); // 自动推导T=std::string,N=2 }
方案3:借助std::to_array(C++20及以上)
用std::to_array把初始化列表直接转成std::array,再传给函数。std::to_array会触发CTAD推导模板参数,函数就能自动拿到N了:
#include <array> #include <string> using namespace std::string_literals; template<size_t N> void Test(const std::array<std::string, N> &argument) { } // 改成const&才能接临时对象 int main(void) { // 直接传临时对象 Test(std::to_array({ "Hello"s, "World"s })); // 或者先存成变量再传 // auto arr = std::to_array({ "Hello"s, "World"s }); // Test(arr); }
注意要把函数参数改成const std::array<...>&,因为std::to_array返回的是临时对象,没法绑定到非const的左值引用。
方案4:用auto模板参数(C++20及以上,适合编译期场景)
如果你的目标是编译期求值,可以让函数接受任意类型的参数,再用类型特征提取std::array的大小:
#include <array> #include <string> #include <type_traits> using namespace std::string_literals; template<typename Arr> requires std::is_same_v<Arr, std::array<std::string, std::tuple_size_v<Arr>>> void Test(Arr &argument) { constexpr size_t N = std::tuple_size_v<Arr>; // 编译期就能拿到N // 这里写编译期逻辑 } int main(void) { auto arr = std::to_array({ "Hello"s, "World"s }); Test(arr); }
内容的提问来源于stack exchange,提问作者Cherestes Radu
相关产品推荐
相关产品推荐

