C++ subMat临时对象绑定非const左值引用报错解决问询
报错根因
C++语法明确禁止非常量左值引用绑定到临时对象(右值),subMat(myBlockMatrix[0])是调用构造函数生成的临时subMat实例,属于右值,自然无法匹配形参为T&的test函数。而sum_of_elements可以正常运行,是因为它的形参是常量左值引用,支持绑定右值。
可落地的解决方案
方案1:修改函数参数为转发引用(成本最低,推荐)
如果可以调整现有模板函数的签名,直接把参数改为转发引用T&&,即可同时支持左值、右值参数传入,且不会修改原有操作逻辑:
template <typename T> void test(T&& arr) // 把T&改成T&&即可 { for (int i=0;i <9; ++i) { arr[i] = 1; } }
修改完成后test(subMat(myBlockMatrix[0]))就可以直接正常运行,不需要其他改动。
方案2:编写通用包装函数(适合无法修改原有函数的场景)
如果针对matrix3编写的函数不可修改(比如是第三方库提供的接口),可以写一个通用的工具函数封装subMat实例创建的逻辑,避免每次手动写声明:
template<typename Func> decltype(auto) run_with_submat(matrix4& mat, Func&& func) { subMat sub(mat); return std::forward<Func>(func)(sub); }
调用时直接写:
run_with_submat(myBlockMatrix[0], test);
方案3:函数按值传参(适合视图类专属场景)
由于subMat是纯视图类,内部仅存储一个指向matrix4的引用,拷贝/移动成本几乎为0,也可以把函数参数改为按值传递:
template <typename T> void test(T arr) { for (int i=0;i <9; ++i) { arr[i] = 1; } }
这种方式也可以直接接收临时subMat对象,且对底层矩阵的修改依然会生效。
问题答疑
- 如何调整该结构以复用此前针对matrix3编写的函数?
不需要修改subMat的现有结构,它已经实现了和matrix3一致的operator[]接口,只要按上述方案调整函数传参方式,即可直接适配所有通过operator[]访问元素的matrix3处理函数。 - 是否必须每次新建subMat实例才能执行操作?
是的,subMat作为绑定特定matrix4的视图,每个实例对应一个matrix4的映射关系,但它的创建没有任何额外性能开销,无需担心成本问题。 - 是否有办法直接在函数参数中使用
subMat(myBlockMatrix[0])的写法?
有,采用上述方案1修改函数参数为转发引用后,即可直接使用该写法,不需要额外声明变量。
内容的提问来源于stack exchange,提问作者user8458838
相关产品推荐
相关产品推荐

