C++如何通过初始化列表大小推导类模板参数以构造内部std::array
你的需求可以在C++17及以上版本中实现,核心依赖**类模板实参推导(CTAD)**能力。
问题原因
你写的目标写法Foo1 f11 = {{1, 2}, {3, 4}}编译失败,是因为类模板默认无法从初始化列表自动推导模板参数N的取值,同时拷贝初始化场景下的初始化列表层级匹配规则和直接初始化有差异,需要手动添加推导指南匹配构造函数的入参规则。
实现代码
#include <array> #include <cstddef> #include <utility> struct Element { int a; int b; }; template <std::size_t N> class Foo1 { public: // 兼容C++17的变参构造函数,直接聚合初始化std::array template<typename... Args> constexpr Foo1(Args&&... args) requires (sizeof...(Args) == N && (std::is_convertible_v<Args, Element> && ...)) : m_Data{Element{std::forward<Args>(args)}...} { } private: std::array<Element, N> m_Data; }; // 关键:CTAD推导指南,自动从入参数量推导N的取值 template<typename... Args> Foo1(Args&&...) -> Foo1<sizeof...(Args)>; int main() { // 目标写法可正常编译运行 Foo1 f11 = { {1, 2}, {3, 4}, }; // 原有直接初始化写法也可正常运行 Foo1 f12({ {1, 2}, {3, 4}, }); }
补充说明
- 如果你使用C++20及以上版本,也可以保留你原有接收数组引用的构造函数,配合
std::to_array完成std::array的初始化,推导指南对应调整为template<std::size_t N> Foo1(Element const (&)[N]) -> Foo1<N>即可。 - 如果你的编译环境只能支持C++14及更早版本,没有CTAD特性,无法实现你要求的语法,必须手动指定模板参数或者额外调用工厂函数构造。
内容的提问来源于stack exchange,提问作者Gary Allen
相关产品推荐
相关产品推荐

