你好,我看到了这个代码。它演示了如何使用dlib库的矩阵结构。
根据这个代码,可以通过以下方式初始化矩阵结构:
M = 54.2, 7.4, 12.1,
1, 2, 3,
5.9, 0.05, 1;
在C++中,这怎么可能实现呢?
这是某种运算符重载吗?
通过重载operator,
(逗号运算符),可以实现这一点,例如将其用于将新的浮点值推送到M
中。
需要注意的一点是,operator,
应该始终至少具有一个类类型参数,因此您需要创建一个隐式可转换为浮点值的类(例如通过具有 1 个类型为 double
或 float
的非 explicit
构造函数)。
例如,我们将尝试对覆盖一个 std::vector
的包装类型进行此操作,并尝试使 M = 1, 2, 3, 4, 5
成为一个有效表达式,其中结果是一个按顺序包含这些元素的 std::vector
。您会发现这很容易适用于您提供的矩阵示例。
需要记住的一点是,operator=
的优先级高于 operator,
(如此运算符优先级表格所示);因此,M = 1, 2, 3, 4, 5
实际上会被解析为:(((((M = 1), 2), 3), 4), 5)
。
鉴于此,我们将从创建具有一个接受单个值并将其推送到容器中的 container
类的 operator=
开始:
template<typename ValueType>
struct container {
explicit container(std::size_t n) {
vec.reserve(n);
}
container& operator=(ValueType a) {
vec.push_back(a);
return (*this);
}
std::vector<ValueType> vec;
};
在这一点上,我们可以将operator
定义为:
template<typename ValueType>
container<ValueType>& operator,(container<ValueType>& m, ValueType a) {
m.vec.push_back(a);
return m;
}
它只是推回一个新的元素值。
现在你可以轻松地看到以下代码可以正常工作并打印出1 2 3 4 5
:
int main() {
container<int> M(5);
M = 1, 2, 3, 4, 5;
for (auto i : M.vec) std::cout << i << ' ';
}
我尽可能地不赞成使用这种技术。它会强制你对其他运算符(例如operator=
)进行奇怪的语义设计,似乎并没有为简单使用std::initializer_list<T>
增加任何东西。
一个更合理的示例是将operator=
定义如下:
container& operator=(std::initializer_list<ValueType> a) {
std::copy(begin(a), end(a), back_inserter(vec));
return (*this);
}
然后只需使用方括号:
int main() {
container<int> M(5);
M = { 1, 2, 3, 4, 5 };
for (auto i : M.vec) std::cout << i << ' ';
}
M
的构造函数,在matrix<double> M(3,3);
的初始化中。 - Shoe
std::initialiser_list
,给出M = {...};
。 - Mike Seymour