C++20及以上:如何将模板参数中的const引用打包为std::array?
在C++20及更高版本中打包模板参数里的constexpr常量引用为数组
问题描述
想要将模板参数列表中传入的constexpr对象的const引用打包为数组,尝试的代码如下(注意参数包展开仅在模板参数列表中,而非函数内部):
using Key = std::string_view; template <const Key & ... KS> consteval auto foo() { return std::to_array<Key>(KS ...); // 编译错误 } constexpr inline Key k1 = "abc"; constexpr inline Key k2 = "xyz"; auto a = foo<k1, k2>();
同时询问是否存在类似std::forward_as_tuple的工具(比如forward_as_array)可以直接使用。
解决方法
原代码编译错误的原因是std::to_array需要接收元素值构造数组,但直接展开KS...时传递的是引用类型,与std::to_array的参数要求不匹配。可以通过以下两种方式解决:
方式一:直接构造std::array
利用模板参数包直接初始化std::array,编译器会自动将引用绑定的constexpr对象的值拷贝到数组元素中:
using Key = std::string_view; template <const Key & ... KS> consteval auto foo() { return std::array<Key, sizeof...(KS)>{KS...}; } constexpr inline Key k1 = "abc"; constexpr inline Key k2 = "xyz"; auto a = foo<k1, k2>(); // 编译通过,a为std::array<std::string_view, 2>,元素为"abc"和"xyz"
方式二:存储引用包装器(如需保留引用关系)
如果需要保留对原constexpr对象的引用而非拷贝值,可以使用std::reference_wrapper包装引用,存储到数组中:
#include <functional> #include <array> #include <string_view> using Key = std::string_view; template <const Key & ... KS> consteval auto foo() { return std::array<std::reference_wrapper<const Key>, sizeof...(KS)>{std::cref(KS)...}; } constexpr inline Key k1 = "abc"; constexpr inline Key k2 = "xyz"; auto a = foo<k1, k2>(); // 数组元素为指向k1、k2的const引用包装器
目前C++标准库中并没有提供类似std::forward_as_tuple的forward_as_array工具,但通过上述两种方式即可实现需求。
内容的提问来源于stack exchange,提问作者Sonullx Liu
相关产品推荐
相关产品推荐

