C++17:如何仅显式指定维度,让编译器推导对称块矩阵的块类型
实现仅需指定维度的对称块矩阵泛型类
问题描述
需要实现一个任意维度的对称块矩阵泛型类,仅存储上三角部分,块的数量为 n*(n+1)/2(n 为维度,示例中 n=3)。当前通过可变参数模板实现时,必须显式指定维度和所有块的类型,希望仅显式指定维度,让编译器自动推导块的类型,但直接省略块类型的写法会触发编译错误。
现有代码
#include <tuple> #include <cstddef> template <size_t Dimension, typename... Blocks> class SymmetricBlockMatrix { public: constexpr SymmetricBlockMatrix(Blocks... blocks): blocks(blocks...) { } constexpr size_t dimension() const { return Dimension; } protected: const std::tuple<Blocks...> blocks; }; // 期望的写法(编译报错) int main() { constexpr SymmetricBlockMatrix<3> m(1, 2, 3, 4, 5, 6); return 0; }
编译错误信息
error: no matching function for call to 'SymmetricBlockMatrix<3>::SymmetricBlockMatrix(int, int, int, int, int, int)'
18 | constexpr SymmetricBlockMatrix<3> m(1, 2, 3, 4, 5, 6);
解决方案
C++ 不支持类模板的部分参数推导(即不能仅显式指定部分模板参数,让编译器推导剩余参数),但可以通过辅助工厂函数来实现需求,同时还能添加静态断言校验块数量是否符合维度要求:
修改后的代码
#include <tuple> #include <cstddef> template <size_t Dimension, typename... Blocks> class SymmetricBlockMatrix { public: constexpr SymmetricBlockMatrix(Blocks... blocks): blocks(blocks...) { } constexpr size_t dimension() const { return Dimension; } protected: const std::tuple<Blocks...> blocks; }; // 工厂函数:仅需指定维度,自动推导块类型,并校验块数量 template <size_t Dimension, typename... Blocks> constexpr auto make_symmetric_block_matrix(Blocks... blocks) { // 静态断言:确保传入的块数量符合维度要求 static_assert(sizeof...(Blocks) == Dimension * (Dimension + 1) / 2, "Number of blocks does not match the matrix dimension"); return SymmetricBlockMatrix<Dimension, Blocks...>(blocks...); } // 使用示例 int main() { // 仅显式指定维度3,块类型int由编译器自动推导 constexpr auto m = make_symmetric_block_matrix<3>(1, 2, 3, 4, 5, 6); // 验证维度 static_assert(m.dimension() == 3); return 0; }
说明
- 工厂函数的作用:通过
make_symmetric_block_matrix<Dimension>(...)的形式,仅需显式指定维度Dimension,编译器会自动推导可变参数Blocks的类型。 - 静态断言校验:添加
static_assert可以在编译期检查传入的块数量是否等于Dimension*(Dimension+1)/2,提前发现错误。 - 兼容性:该方案兼容C++17及以上版本,符合constexpr要求,支持编译期构造。
内容的提问来源于stack exchange,提问作者Charlie Vanaret - the Uno guy
相关产品推荐
相关产品推荐

