xtensor选取指定字符串列值行时xt::equal触发编译错误
错误产生原因
xtensor的核心运算默认返回惰性求值的表达式模板对象,而非立即计算完成的实体张量:
- 你代码里的
n1虽然打印输出看起来是整数序列{1, 0, 0, 0, 0},但它本质是绑定了原xt::xtensor<std::string, 2>数据源的求和表达式,没有被显式求值为独立的整数类型张量。 - 当调用
xt::equal(n1, 1)时,编译器需要沿着表达式模板的类型链生成逐元素比较的代码,会回溯到原始数组的std::string元素类型,尝试推导std::string和整数1的比较逻辑,过程中触发了std::string未定义operator+的类型检查报错——这不是n1实际存储了字符串,是未求值的惰性表达式导致类型推导穿透到了原始数据源的元素类型。
修复实现方案
你不需要走「布尔结果求和再判断是否等于1」的绕路逻辑,字符串等值比较返回的布尔结果本身就是可用的行掩码,直接对掩码做索引提取即可,修复后的可运行代码如下:
#include <vector> #include <iostream> #include <string> #include <numeric> #include <limits> #undef max #undef min #define NOMINMAX #include <xtensor/xtensor.hpp> #include <xtensor/xview.hpp> #include <xtensor/xio.hpp> int main() { xt::xtensor <std::string, 2> xtAudit = { {"Cell1", "A1", "B1"}, {"Cell2", "A2", "B2"}, {"Cell3", "A3", "B3"}, {"Cell4", "A4", "B4"}, {"Cell5", "A5", "B5"} }; std::string strCell = "Cell1"; // 直接取第0列做等值比较,无需用keep(0)额外嵌套维度 auto col_mask = xt::equal(xt::view(xtAudit, xt::all(), 0), strCell); // 提取匹配行的索引 auto match_indices = xt::flatten_indices(xt::argwhere(col_mask)); // 按索引筛选目标行 auto res = xt::view(xtAudit, xt::keep(match_indices), xt::all()); std::cout << res << std::endl; return 0; }
如果确实要保留求和判断的写法,只需要对sum结果做显式求值,指定结果为整数类型的实体张量,切断和原字符串数组的类型关联即可,替换原代码中n1的定义行:
// 替换原代码中 auto n1 = xt::sum(test1, 1); xt::xtensor<size_t, 1> n1 = xt::sum(test1, 1);
代码运行后的正确输出为:
{{"Cell1", "A1", "B1"}}
内容的提问来源于stack exchange,提问作者Chris S
相关产品推荐
相关产品推荐

