c ++ - 使用逗号分隔值进行矩阵初始化

时间:2015-05-28 13:51:49

标签: c++

您好我遇到了这段code。它演示了如何使用dlib库的矩阵结构。

根据这个,可以通过以下方式初始化矩阵结构:

M = 54.2,  7.4,  12.1,
    1,     2,    3,
    5.9,   0.05, 1;

如何在C ++中实现这一点?

这是某种运算符重载吗?

1 个答案:

答案 0 :(得分:12)

逻辑

这可以通过重载operator,(运算符逗号)来实现,例如使其将新的浮点值推送到M

需要注意的是operator,应始终至少有一个类类型的参数,因此您必须创建一个可隐式转换为浮点值的类(例如,通过非explicit构造函数,其中包含1个doublefloat类型的参数。

实施例

例如,我们尝试针对std::vector上的包装类型执行此操作,我们会尝试使M = 1, 2, 3, 4, 5成为有效的表达式,从而产生{{1}这些元素按顺序排列。您会发现这很容易适用于您提供的矩阵示例。

要记住的一点是std::vector优先于operator=(如this table of operator precedence所示);因此,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 << ' ';
}

Live demo

考虑

我尽可能地劝阻这种技术。它迫使你为其他运算符(例如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 << ' ';
}

Live demo