You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让C++模板函数同时兼容二维数组与vector<vector>参数?

问题描述

现有如下C++模板函数,用于接收二维数组形式的邻接矩阵,遍历并输出所有非默认值的边,同时调用传入的访问器:

template <typename Edge, std::size_t N, typename Visitor>
void report_edges(const Edge (&AdjacencyMatrix)[N][N], Visitor &&visitor) {
    for (size_t i = 0; i < N; ++i) {
        for (size_t j = i + 1; j < N; ++j) {
            if (AdjacencyMatrix[i][j] != Edge{}) {
                visitor(i, j);
                std::cout << i << " -<" << AdjacencyMatrix[i][j] << ">-" << j << std::endl;
            }
        }
    }
}

需要改写该函数,要求:

  • 同一模板函数同时支持二维数组和std::vector<std::vector<Edge>>作为输入参数
  • 禁止编写外部辅助函数

尝试移除模板参数std::size_t N仅保留Edge模板时,会对二维数组类型产生编译错误,需解决此问题。

解决方案

核心思路是将矩阵类型设为通用模板参数,不再固定为二维数组,利用C标准库的std::size(C17及以上)统一获取矩阵维度——该函数对内置数组和标准容器(如vector)均有效。修改后的代码如下:

#include <vector>
#include <iostream>
#include <iterator> // 包含std::size

template <typename Matrix, typename Visitor>
void report_edges(const Matrix& adjacency_matrix, Visitor&& visitor) {
    using EdgeType = std::decay_t<decltype(adjacency_matrix[0][0])>;
    const auto size = std::size(adjacency_matrix);
    
    for (std::size_t i = 0; i < size; ++i) {
        // 假设邻接矩阵是方阵,若需支持非方阵可单独获取列数
        const auto row_size = std::size(adjacency_matrix[i]);
        for (std::size_t j = i + 1; j < row_size; ++j) {
            if (adjacency_matrix[i][j] != EdgeType{}) {
                visitor(i, j);
                std::cout << i << " -<" << adjacency_matrix[i][j] << ">-" << j << std::endl;
            }
        }
    }
}
代码说明
  1. 模板参数调整:将原有的Edge和N合并为通用的Matrix模板参数,适配任意支持[]访问和std::size的二维容器/数组类型。
  2. Edge类型推导:通过decltype(adjacency_matrix[0][0])获取元素类型,用std::decay_t去除引用和cv限定符,得到原始的边类型。
  3. 维度获取:std::size(adjacency_matrix)对二维数组返回编译期常量N,对vector<vector>返回运行时的size()值,实现统一处理。
  4. 兼容性:无需额外函数,同一个模板即可处理两种输入类型,符合要求。
测试示例
// 测试二维数组
int arr[3][3] = {
    {0, 1, 0},
    {0, 0, 2},
    {0, 0, 0}
};

// 测试vector<vector>
std::vector<std::vector<int>> vec = {
    {0, 3, 0},
    {0, 0, 4},
    {0, 0, 0}
};

// 简单的访问器函数
void print_visitor(std::size_t from, std::size_t to) {
    std::cout << "Visited edge: " << from << " -> " << to << "\n";
}

int main() {
    std::cout << "=== Testing array ===\n";
    report_edges(arr, print_visitor);
    
    std::cout << "\n=== Testing vector ===\n";
    report_edges(vec, print_visitor);
    
    return 0;
}

输出结果:

=== Testing array ===
Visited edge: 0 -> 1
0 -<1>- 1
Visited edge: 1 -> 2
1 -<2>- 2

=== Testing vector ===
Visited edge: 0 -> 1
0 -<3>- 1
Visited edge: 1 -> 2
1 -<4>- 2

内容的提问来源于stack exchange,提问作者manull

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:31:00