如果您的值类型相对简单,Evgeny 的答案是迄今为止最好的。
但是,如果您想重新创建real()
和complex()
(访问Scalar
s 结构的部分),您可以使用const_cast<>
它来破解它,这就是real/complex()
实际所做的(从 v3.3.3 开始):(注意:此代码仅在 C+ 中测试过+1y,但可以简化。)
struct Value {
double a{1.5};
int b{2};
};
// Savage. Use aforemention hack from scalar_real_ref_op.
struct get_mutable_a_direct {
double& operator()(const Value& v) const {
return const_cast<Value&>(v).a;
}
};
// ...
MatrixX<Value> X(2, 2);
auto X_am_direct = CwiseUnaryView<get_mutable_a_direct, MatrixX<Value>>(
X, get_mutable_a_direct());
X_am_direct.setConstant(20);
我还测试了一个快速包装器,以将上述内容简化为:
struct get_a_flex {
double& operator()(Value& v) const {
return v.a;
}
const double& operator()(const Value& v) const {
return v.a;
}
};
// Less? savage.
auto X_am = unaryExprFlex(X, get_a_flex());
X_am *= 10;
cout << X_ac << endl;
// Works.
const auto& Xc = X;
auto Xc_am = unaryExprFlex(Xc, get_a_flex());
// Xc_am.setConstant(20); // Fails as desired.
cout << Xc_am << endl;
您可以在此处查看代码片段:unary_view_mutable.cc
注意:如果您想使用 labmda,请务必指明通过以下方式返回参考auto&
:
auto X_bm = unaryExprFlex(X, [](Value& v) -> auto& { return v.b; });
cout << X_bm << endl;
X_bm.setConstant(10);
cout << X_bm << endl;